diff --git a/.github/workflows/markdown-lint-fix.yml b/.github/workflows/markdown-lint-fix.yml index 61b8eb91770af8..7440889f0d406d 100644 --- a/.github/workflows/markdown-lint-fix.yml +++ b/.github/workflows/markdown-lint-fix.yml @@ -25,7 +25,7 @@ jobs: - uses: actions/checkout@v4 - name: Setup Node.js environment - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version-file: ".nvmrc" cache: yarn @@ -44,7 +44,7 @@ jobs: path: mdn/content - name: Setup Node.js environment for mdn/content - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version-file: ".nvmrc" cache: "yarn" diff --git a/.github/workflows/markdown-lint.yml b/.github/workflows/markdown-lint.yml index 63e7cdad0b97fd..c74fffebc7b90c 100644 --- a/.github/workflows/markdown-lint.yml +++ b/.github/workflows/markdown-lint.yml @@ -23,7 +23,7 @@ jobs: - uses: actions/checkout@v4 - name: Setup Node.js environment - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version-file: ".nvmrc" cache: yarn diff --git a/.github/workflows/pr-check-lint_content.yml b/.github/workflows/pr-check-lint_content.yml index 643cfd81a9afd6..9b0910d33d6f58 100644 --- a/.github/workflows/pr-check-lint_content.yml +++ b/.github/workflows/pr-check-lint_content.yml @@ -69,7 +69,7 @@ jobs: - name: Setup Node.js environment if: ${{ env.DIFF_DOCUMENTS }} - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version-file: ".nvmrc" cache: yarn diff --git a/.github/workflows/pr-check_json.yml b/.github/workflows/pr-check_json.yml index 2426af09d6461e..d56d8ecd0bee5f 100644 --- a/.github/workflows/pr-check_json.yml +++ b/.github/workflows/pr-check_json.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/checkout@v4 - name: Setup Node.js environment - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version-file: ".nvmrc" cache: yarn diff --git a/.github/workflows/pr-check_redirects.yml b/.github/workflows/pr-check_redirects.yml index a8015f16ddaca8..090e956c7e5c97 100644 --- a/.github/workflows/pr-check_redirects.yml +++ b/.github/workflows/pr-check_redirects.yml @@ -24,7 +24,7 @@ jobs: path: mdn/content - name: Setup Node.js environment - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version-file: ".nvmrc" cache: "yarn" diff --git a/.github/workflows/pr-check_yml.yml b/.github/workflows/pr-check_yml.yml index c6ac78d8b92034..230ad516169117 100644 --- a/.github/workflows/pr-check_yml.yml +++ b/.github/workflows/pr-check_yml.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/checkout@v4 - name: Setup Node.js environment - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version-file: ".nvmrc" cache: yarn diff --git a/.github/workflows/pr-test.yml b/.github/workflows/pr-test.yml index cec98bebb4f1a0..436097ca663866 100644 --- a/.github/workflows/pr-test.yml +++ b/.github/workflows/pr-test.yml @@ -41,7 +41,7 @@ jobs: path: mdn/content - name: Setup Node.js environment - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version-file: ".nvmrc" cache: "yarn" diff --git a/.github/workflows/sync-translated-content.yml b/.github/workflows/sync-translated-content.yml index 9a2da220f6b783..d12f4af5ca66d2 100644 --- a/.github/workflows/sync-translated-content.yml +++ b/.github/workflows/sync-translated-content.yml @@ -39,7 +39,7 @@ jobs: path: mdn/content - name: Setup Node.js environment - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version-file: ".nvmrc" cache: "yarn" diff --git a/.gitignore b/.gitignore index bf14aa8a6b5866..c8e645ae63bbdf 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ _githistory.json .DS_Store .idea +.vscode mdn/content yarn-debug.log* yarn-error.log* diff --git a/docs/ko/fully_untranslated_files/Learn_Forms_Sending_and_retrieving_form_data.md b/docs/ko/fully_untranslated_files/Learn_Forms_Sending_and_retrieving_form_data.md index 42310097e096ee..a50a0b909e2975 100644 --- a/docs/ko/fully_untranslated_files/Learn_Forms_Sending_and_retrieving_form_data.md +++ b/docs/ko/fully_untranslated_files/Learn_Forms_Sending_and_retrieving_form_data.md @@ -9,7 +9,7 @@ slug: Learn/Forms/Sending_and_retrieving_form_data ### 클라이언트/서버 구조 -웹은 간단히 말하면 클라이언트(파이어폭스, 크롬, 사파리, IE 등)는 서버(아파치, Nginx, IIS, 톰켓 등)로 HTTP프로토콜을 사용해 요청을 하는 클라이언트/서버 구조를 기본으로 작동된다. 서버 응답은 요청과 똑같은 프로토콜을 사용한다. +웹은 간단히 말하면 클라이언트(Firefox, 크롬, Safari, IE 등)는 서버(아파치, Nginx, IIS, 톰켓 등)로 HTTP프로토콜을 사용해 요청을 하는 클라이언트/서버 구조를 기본으로 작동된다. 서버 응답은 요청과 똑같은 프로토콜을 사용한다. ![A basic schema of the Web client/server architecture](/files/4291/client-server.png) @@ -109,7 +109,7 @@ say=Hi&to=Mom Content-Length 헤더는 바디의 크기를 나태내고, Content-Type 헤더는 서버에 보낼 리소스의 종류 나태낸다. 우리는 비트(bit/조금씩?)에서 이러한 헤더를 설명 할 것이다. -물론 http 요청은 절대 사용자에게 표시되지 않는다(파이어폭스 웹 콘솔이나 크롬 개발자 툴을 이용하지 않는이상). 사용자에게 보여지는 것은 호출한 URL뿐이다. 그래서 GET 요청은 사용자에게 URL바에서 데이터를 볼 수있지만, POST 요청은 그러지 못한다. 이것은 두가지 이유에서 매우 중요하다. +물론 http 요청은 절대 사용자에게 표시되지 않는다(Firefox 웹 콘솔이나 크롬 개발자 툴을 이용하지 않는이상). 사용자에게 보여지는 것은 호출한 URL뿐이다. 그래서 GET 요청은 사용자에게 URL바에서 데이터를 볼 수있지만, POST 요청은 그러지 못한다. 이것은 두가지 이유에서 매우 중요하다. 1. 만약 패스워드를 전송해야 되는 경우(또는 민간한 데이터의 부분), 절대 URL 바에 데이터를 출력하는 GET 방식을 사용해서는 안된다. 2. 만약 거대한 데이터를 보내는경우 POST 방식이 선호 된다. 왜냐하면 몇몇 브라우저는 URL들의 크기를 제한하기 떄문이다. 또한 많은 서버들이 URL들의 길이를 제한한다. diff --git a/docs/ko/fully_untranslated_files/Learn_JavaScript_Client-side_web_APIs_Client-side_storage.md b/docs/ko/fully_untranslated_files/Learn_JavaScript_Client-side_web_APIs_Client-side_storage.md index a27bb3739b4de6..17f13eb642d1a0 100644 --- a/docs/ko/fully_untranslated_files/Learn_JavaScript_Client-side_web_APIs_Client-side_storage.md +++ b/docs/ko/fully_untranslated_files/Learn_JavaScript_Client-side_web_APIs_Client-side_storage.md @@ -37,7 +37,7 @@ slug: Learn/JavaScript/Client-side_web_APIs/Client-side_storage 우리는 다른 MDN 학습영역에서 [정적인 사이트](/ko/docs/Learn/Server-side/First_steps/Client-Server_overview#Static_sites)와 [동적인 사이트](/ko/docs/Learn/Server-side/First_steps/Client-Server_overview#Dynamic_sites)에 대해 이미 설명하였습니다. 현대의 대부분의 웹사이트들은 어떤 데이터베이스(서버의 저장소)를 이용하여 서버에 데이터를 저장하고, 필요한 데이터를 찾아오기 위해 [서버-사이드](/ko/docs/Learn/Server-side) 코드를 돌리고, 정적인 페이지 템플릿에 데이터를 삽입하고, HTML 결과물을 사용자의 브라우저에 표시될 수 있게 제공합니다 - 즉 동적입니다. -클라이언트-사이드 저장소는 비슷한 원리로 작동하지만, 다르게 쓰입니다. 이것은 개발자가 클라이언트 측(사용자의 컴퓨터 등)에 데이터를 저장할 수 있고 필요할 때 가져올 수 있게 해주는 자바스크립트 API로 구성되어 있습니다. 이것의 다양한 용도는 다음과 같습니다. +클라이언트-사이드 저장소는 비슷한 원리로 작동하지만, 다르게 쓰입니다. 이것은 개발자가 클라이언트 측(사용자의 컴퓨터 등)에 데이터를 저장할 수 있고 필요할 때 가져올 수 있게 해주는 JavaScript API로 구성되어 있습니다. 이것의 다양한 용도는 다음과 같습니다. - 웹사이트에 대한 선호를 개인화하기(사용자가 선택한 커스텀 위젯, 배색, 폰트 크기로 보여주기) - 이전 활동 기록 저장하기(이전 세션에 담았던 장바구니 목록 저장하기, 로그인 유지하기) diff --git a/docs/ko/fully_untranslated_files/Learn_Server-side_Express_Nodejs_Introduction.md b/docs/ko/fully_untranslated_files/Learn_Server-side_Express_Nodejs_Introduction.md index ef687cd859052b..141a245df75025 100644 --- a/docs/ko/fully_untranslated_files/Learn_Server-side_Express_Nodejs_Introduction.md +++ b/docs/ko/fully_untranslated_files/Learn_Server-side_Express_Nodejs_Introduction.md @@ -34,13 +34,13 @@ slug: Learn/Server-side/Express_Nodejs/Introduction ## Express와 Node란? -[Node](https://nodejs.org/) (또는 더 공식적으로는 Node.js) 는 오픈소스, 크로스 플랫폼이며, 개발자가 모든 종류의 서버 사이드 도구들과 어플리케이션을 [JavaScript](/ko/docs/Glossary/JavaScript)로 만들수 있도록 해주는 런타임 환경이다.런타임은 브라우져 영역 밖에서도 사용할수 있도록 의도했다.(예를들면 서버 OS 또는 컴퓨터에서 직접적으로 실행되는). 이와 같이, 이 환경에서 특정 브라우져에서의 자바스트립트 API들을 제외시키고 , HTTP 와 파일 시스템 라이브러리들을 포함하여 더 많은 전형적인 OS API들을 추가했다. +[Node](https://nodejs.org/) (또는 더 공식적으로는 Node.js) 는 오픈소스, 크로스 플랫폼이며, 개발자가 모든 종류의 서버 사이드 도구들과 어플리케이션을 [JavaScript](/ko/docs/Glossary/JavaScript)로 만들수 있도록 해주는 런타임 환경이다.런타임은 브라우져 영역 밖에서도 사용할수 있도록 의도했다.(예를들면 서버 OS 또는 컴퓨터에서 직접적으로 실행되는). 이와 같이, 이 환경에서 특정 브라우져에서의 JavaScript API들을 제외시키고 , HTTP 와 파일 시스템 라이브러리들을 포함하여 더 많은 전형적인 OS API들을 추가했다. 웹 서버 관점에서 노드는 많은 장점들을 가진다: - 훌륭한 퍼포먼스! Node는 단위시간당 처리량과 어플리케이션에서 확장성을 최적화 시키고, 많은 공통적인 웹 개발 문제들을 맞먹는다.(예를들면 실시간 웹 어플리케이션들) -- 코드는 순수한 자바스크립트로 작성된다, 이는 당신이 각각 브라우져와 웹 서버 코드를 작성할때 언어들 사이에 "context shift" 를 다루는 시간을 적게 할수 있을을 의미한다. -- 자바스크립트는 비교적 새로운 프로그래밍 언어이고 또다른 전통적인 웹서버 언어들과 비교할때 언어적 설계에서 향상의 이득을 가진다. 많은 다른 새롭거나 인기있는 언어들은 자바스크립트로 컴파일하거나 변환한다 그래서 또한 당신은 커피스크립트, 클로져스크립트, 스칼라, 라이브 스크립트 등등을 사용할 수 있다. +- 코드는 순수한 JavaScript로 작성된다, 이는 당신이 각각 브라우져와 웹 서버 코드를 작성할때 언어들 사이에 "context shift" 를 다루는 시간을 적게 할수 있을을 의미한다. +- JavaScript는 비교적 새로운 프로그래밍 언어이고 또다른 전통적인 웹서버 언어들과 비교할때 언어적 설계에서 향상의 이득을 가진다. 많은 다른 새롭거나 인기있는 언어들은 JavaScript로 컴파일하거나 변환한다 그래서 또한 당신은 커피스크립트, 클로져스크립트, 스칼라, 라이브 스크립트 등등을 사용할 수 있다. - 노드 패키지 매니저(NPM)는 수천만개의 재사용가능한 패키지에 접근할 수 있도록 한다. 이것은 최고의 의존성 해결과 또한 수많은 빌드 툴체인이 자동화되도록 한다. - 이것은 마이크로소프트 윈도우, OS X, 룩스, 솔라리스, FreeBSD, OpenBSD, WebOS, 그리고 NonStop OS 등에서 돌아가는 버전과 같이 포터플하다. 더군다나, 이것은 특정한 인프라구조를 지원하고 Node 사이트 호스팅을 위한 문서를 제공하는 많은 웹 호스팅 공급자들에 의해서 잘 지원되고 있다. - 도움을 주고자 하는 수많은 사람들이 존재하는 아주 활발한 개발 생태계와 커뮤니티를 지니고 있다. diff --git a/docs/ko/fully_untranslated_files/Web_API_IndexedDB_API_Basic_Terminology.md b/docs/ko/fully_untranslated_files/Web_API_IndexedDB_API_Basic_Terminology.md index cd99c3b550577b..39d599e156c436 100644 --- a/docs/ko/fully_untranslated_files/Web_API_IndexedDB_API_Basic_Terminology.md +++ b/docs/ko/fully_untranslated_files/Web_API_IndexedDB_API_Basic_Terminology.md @@ -31,7 +31,7 @@ IndexedDB는 "키"로 인덱싱된 객체를 저장하고 검색할 수 있습 - **IndexedDB는 결과를 사용할 수 있을 때 DOM 이벤트를 통해 통지합니다.** DOM 이벤트는 항상 `type` 프로퍼티를 가집니다 (IndexedDB에서는 거의 대부분 `"success"` 또는 `"error"`로 설정됩니다.). DOM 이벤트는 이벤트가 향하는 곳이 어디인지를 나타내는 `target` 프로퍼티도 가집니다. 대부분의 경우에, 이벤트의 `target` 프로퍼티는 데이터베이스 동작의 결과로 생성된 `IDBRequest` 객체를 가리킵니다. 성공 이벤트는 버블링을 일으키지 않으며, 취소될 수 없습니다. 에러 이벤트는 반대로 버블링을 일으키고, 취소될 수도 있습니다. 에러 이벤트는 취소되지 않는 한 실행 중인 모든 트랜잭션을 중단하므로 이는 매우 중요합니다. - **IndexedDB는 객체지향적입니다.** IndexedDB는 행과 열의 컬렉션으로 대표되는 테이블을 사용하는 관계형 데이터베이스가 아닙니다. 이는 어플리케이션을 설계하고 구축하는 방식에 영향을 끼치는 중요하고 근본적인 차이입니다. - 전통적인 관계형 데이터 저장소에서는 데이터 행의 컬렉션과 명명된 자료형의 데이터 열을 저장하는 테이블을 갖습니다. 반면에 IndexedDB는 특정 타입의 데이터를 저장할 객체 저장소를 생성하고, 자바스크립트 객체를 저장소에 저장합니다. 각 객체 저장소는 쿼리와 순회를 효율적으로 만들어주는 인덱스 컬렉션을 갖습니다. 만약 객체지향 데이터베이스 관리 시스템에 친숙하지 않다면, [객체지향 데이터베이스에 대한 Wikipedia 문서](https://en.wikipedia.org/wiki/Object_database)를 읽어보세요. + 전통적인 관계형 데이터 저장소에서는 데이터 행의 컬렉션과 명명된 자료형의 데이터 열을 저장하는 테이블을 갖습니다. 반면에 IndexedDB는 특정 타입의 데이터를 저장할 객체 저장소를 생성하고, JavaScript 객체를 저장소에 저장합니다. 각 객체 저장소는 쿼리와 순회를 효율적으로 만들어주는 인덱스 컬렉션을 갖습니다. 만약 객체지향 데이터베이스 관리 시스템에 친숙하지 않다면, [객체지향 데이터베이스에 대한 Wikipedia 문서](https://en.wikipedia.org/wiki/Object_database)를 읽어보세요. - **IndexedDB does not use Structured Query Language (SQL).** It uses queries on an index that produces a cursor, which you use to iterate across the result set. If you are not familiar with NoSQL systems, read the [Wikipedia article on NoSQL](https://en.wikipedia.org/wiki/NoSQL). - **IndexedDB adheres to a same-origin policy**. An origin is the domain, application layer protocol, and port of a URL of the document where the script is being executed. Each origin has its own associated set of databases. Every database has a name that identifies it within an origin. diff --git a/docs/ko/fully_untranslated_files/Web_API_Service_Worker_API_Using_Service_Workers.md b/docs/ko/fully_untranslated_files/Web_API_Service_Worker_API_Using_Service_Workers.md index 249190cca1a916..dcc91253e4db49 100644 --- a/docs/ko/fully_untranslated_files/Web_API_Service_Worker_API_Using_Service_Workers.md +++ b/docs/ko/fully_untranslated_files/Web_API_Service_Worker_API_Using_Service_Workers.md @@ -17,7 +17,7 @@ slug: Web/API/Service_Worker_API/Using_Service_Workers > **참고:** Firefox 44에서 [AppCache](/ko/docs/Web/HTML/Using_the_application_cache) 를 사용해서 페이지의 오프라인 지원을 제공할 경우 콘솔에 [서비스 워커](/ko/docs/Web/API/Service_Worker_API/Using_Service_Workers) 를 대신 사용하는것에 대한 제안이 경고로 표시됩니다. ([Firefox bug 1204581](https://bugzil.la/1204581)) -서비스 워커는 최종적으로 이러한 문제를 해결해야 합니다. 서비스 워커 구문은 [AppCache](/ko/docs/Web/HTML/Using_the_application_cache) 보다 복잡하지만, 자바스크립트를 사용해서 세밀하게 [AppCache](/ko/docs/Web/HTML/Using_the_application_cache) 의 암묵적인 동작들을 제어할 수 있으므로 이 문제 그 이상을 처리 할 수 있습니다. 서비스 워커를 사용하면 먼저 캐싱된 리소스를 사용하도록 앱을 설정해서 오프라인일 경우에도 일관적인 경험을 제공한다음 네트워크 연결이 돌아올 때 더 많은 데이터를 불러오게 할 수 있습니다. (보통 [오프라인 우선](http://offlinefirst.org/) 이라고 함) 이 기능은 네이티브 앱에서는 이미 널리 사용되는 구현법이며, 이는 네이티브 앱이 웹 앱 대신 선택되는 주된 이유 중 하나입니다. +서비스 워커는 최종적으로 이러한 문제를 해결해야 합니다. 서비스 워커 구문은 [AppCache](/ko/docs/Web/HTML/Using_the_application_cache) 보다 복잡하지만, JavaScript를 사용해서 세밀하게 [AppCache](/ko/docs/Web/HTML/Using_the_application_cache) 의 암묵적인 동작들을 제어할 수 있으므로 이 문제 그 이상을 처리 할 수 있습니다. 서비스 워커를 사용하면 먼저 캐싱된 리소스를 사용하도록 앱을 설정해서 오프라인일 경우에도 일관적인 경험을 제공한다음 네트워크 연결이 돌아올 때 더 많은 데이터를 불러오게 할 수 있습니다. (보통 [오프라인 우선](http://offlinefirst.org/) 이라고 함) 이 기능은 네이티브 앱에서는 이미 널리 사용되는 구현법이며, 이는 네이티브 앱이 웹 앱 대신 선택되는 주된 이유 중 하나입니다. ## 서비스워커 개발을 위한 환경 설정 @@ -36,7 +36,7 @@ slug: Web/API/Service_Worker_API/Using_Service_Workers 1. {{domxref("serviceWorkerContainer.register()")}}을 통해서 서비스 워커 URL을 가져오고, 등록합니다. 2. 등록에 성공하면, {{domxref("ServiceWorkerGlobalScope") }} 범위에서 서비스 워커가 실행됩니다. 이는 (메인 스크립트 실행 쓰레드를 running off하면서) 기본적으로 DOM 접근이 없는 작업 문맥을 갖습니다. 3. 이제 서비스 워커는 이벤트를 처리할 준비가 되었습니다. -4. 서비스 워커가 제어하는 페이지들에 연속적으로 접근하게 될 때 서비스 워커 설치를 시도하게 됩니다. 서비스 워커는 항상 처음으로 설치 이벤트를 받습니다.(설치 이벤트는 IndexedDB를 생성하고, 사이트 assets을 캐싱하는 처리를 시작할 때 사용될 수 있습니다.) 설치 이벤트는 모든 것을 오프라인에서 사용할 수 있게 하는, 네이티브 또는 파이어폭스 OS 앱을 설치하는 프로시저와 같은 종류입니다. +4. 서비스 워커가 제어하는 페이지들에 연속적으로 접근하게 될 때 서비스 워커 설치를 시도하게 됩니다. 서비스 워커는 항상 처음으로 설치 이벤트를 받습니다.(설치 이벤트는 IndexedDB를 생성하고, 사이트 assets을 캐싱하는 처리를 시작할 때 사용될 수 있습니다.) 설치 이벤트는 모든 것을 오프라인에서 사용할 수 있게 하는, 네이티브 또는 Firefox OS 앱을 설치하는 프로시저와 같은 종류입니다. 5. `oninstall` 핸들러가 완료되면, 서비스 워커가 설치되었다고 할 수 있습니다. 6. 다음은 활성(activation) 이벤트입니다. 서비스 워커가 설치되면, 활성 이벤트를 받게 됩니다. `onactivate` 는 이전 버전의 서비스 워커 스크립트에서 사용된 리소스들을 삭제하는 용도로서 주로 사용됩니다. 7. 이제 서비스 워커가 페이지들을 제어하게 될 것이지만, 오직 `register()` 가 성공적으로 수행된 후에 페이지들이 열리게 될 것입니다. 즉, 문서는 서비스 워커와 함께, 또는 없이도 라이프를 시작하고 유지합니다. 따라서 문서는 실제로 서비스 워커에 제어되기 위해서 재시작 되어야 할 것입니다. diff --git a/docs/ko/fully_untranslated_files/Web_API_Web_Storage_API_Using_the_Web_Storage_API.md b/docs/ko/fully_untranslated_files/Web_API_Web_Storage_API_Using_the_Web_Storage_API.md index 4f08f01f3cc599..cdcb6ab6732627 100644 --- a/docs/ko/fully_untranslated_files/Web_API_Web_Storage_API_Using_the_Web_Storage_API.md +++ b/docs/ko/fully_untranslated_files/Web_API_Web_Storage_API_Using_the_Web_Storage_API.md @@ -11,7 +11,7 @@ Web Storage API는 브라우저에서 쿠키를 사용하는 것보다 훨씬 ## 기본 컨셉 -Storage 객체는 단순한 key-value 저장소이며, 이는 객체와 비슷합니다. 하지만 이 데이터들은 페이지 로딩에도 온전하게 유지됩니다. key와 그 value는 항상 문자열입니다. (만약 정수로 키를 사용할 경우 이는 자동으로 string으로 변경됩니다, 자바스크립트 객체의 동작방식을 생각해보세요) 객체를 사용하듯이 쉽게 값에 접근할 수 있으며, 이 때 {{domxref("Storage.getItem()")}}과 {{domxref("Storage.setItem()")}} 메서드를 사용할 수 있습니다. 아래 세 줄은 (동일한) colorSetting 엔트리에 값을 설정하는 방법입니다. +Storage 객체는 단순한 key-value 저장소이며, 이는 객체와 비슷합니다. 하지만 이 데이터들은 페이지 로딩에도 온전하게 유지됩니다. key와 그 value는 항상 문자열입니다. (만약 정수로 키를 사용할 경우 이는 자동으로 string으로 변경됩니다, JavaScript 객체의 동작방식을 생각해보세요) 객체를 사용하듯이 쉽게 값에 접근할 수 있으며, 이 때 {{domxref("Storage.getItem()")}}과 {{domxref("Storage.setItem()")}} 메서드를 사용할 수 있습니다. 아래 세 줄은 (동일한) colorSetting 엔트리에 값을 설정하는 방법입니다.
localStorage.colorSetting = '#a4509b';
 localStorage['colorSetting'] = '#a4509b';
@@ -35,7 +35,7 @@ localStorage를 사용하려면 먼저 현재 브라우징 세션에서 지원
 
 ### 사용 가능 검사
 
-localStorage를 지원하는 브라우저는 windows 객체에 localStorage라는 property가 존재 합니다. 그러나 여러 가지 이유로 인해 예외가 발생할 수 있습니다. 존재한다 해도 다양한 브라우저가 localStorage를 비활성화하는 설정을 제공하기 때문에 localStorage가 실제로 사용 가능하다는 보장은 없습니다. 따라서 브라우저가 localStorage를 지원한다고 해도 스크립트에서 사용 하지 못 할 수도 있습니다. 예를 들어 사파리 브라우저의 사생활 보호 모드에서 할당량이 0 인 빈 localStorage 개체를 제공하므로 효과적으로 사용할 수 없게 만듭니다. 이때 QuotaExceededError를 얻을 수도 있습니다. 이는 사용가능한 저장공간을 모두 소모 했다는 의미로, localStorage를 사용할 수 없음을 뜻합니다. 이러한 시나리오를 고려하여 사용가능 여부를 검사하여야 합니다.
+localStorage를 지원하는 브라우저는 windows 객체에 localStorage라는 property가 존재 합니다. 그러나 여러 가지 이유로 인해 예외가 발생할 수 있습니다. 존재한다 해도 다양한 브라우저가 localStorage를 비활성화하는 설정을 제공하기 때문에 localStorage가 실제로 사용 가능하다는 보장은 없습니다. 따라서 브라우저가 localStorage를 지원한다고 해도 스크립트에서 사용 하지 못 할 수도 있습니다. 예를 들어 Safari 브라우저의 사생활 보호 모드에서 할당량이 0 인 빈 localStorage 개체를 제공하므로 효과적으로 사용할 수 없게 만듭니다. 이때 QuotaExceededError를 얻을 수도 있습니다. 이는 사용가능한 저장공간을 모두 소모 했다는 의미로, localStorage를 사용할 수 없음을 뜻합니다. 이러한 시나리오를 고려하여 사용가능 여부를 검사하여야 합니다.
 
 다음은 localStorage가 지원되고 사용 가능한지 여부를 감지하는 함수입니다.
 
diff --git a/docs/ko/fully_untranslated_files/Web_API_Web_Workers_API_Using_web_workers.md b/docs/ko/fully_untranslated_files/Web_API_Web_Workers_API_Using_web_workers.md
index 300135c697e327..bb0506c5924c6a 100644
--- a/docs/ko/fully_untranslated_files/Web_API_Web_Workers_API_Using_web_workers.md
+++ b/docs/ko/fully_untranslated_files/Web_API_Web_Workers_API_Using_web_workers.md
@@ -7,7 +7,7 @@ slug: Web/API/Web_Workers_API/Using_web_workers
 
 ## Web Workers API
 
-Worker는 생성자(예를 들면 {{domxref("Worker.Worker", "Worker()")}})를 사용하여 생성된 객체이며 이름있는 자바스크립트 파일(이 파일은 Worker 스레드에서 실행하는 코드를 가집니다)을 실행합니다. 또한 Worker는 현재의 {{domxref("window")}}와는 다른 글로벌 컨텍스트에서 실행됩니다. 따라서 {{domxref("Worker")}} 내에서 현재의 글로벌 스코프를 접근하기 위해 ({{domxref("window.self","self")}} 대신에) {{domxref("window")}}를 사용해도 오류가 돌아옵니다.
+Worker는 생성자(예를 들면 {{domxref("Worker.Worker", "Worker()")}})를 사용하여 생성된 객체이며 이름있는 JavaScript 파일(이 파일은 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는, 복수의 스크립트에서 액세스 할 수 있습니다.
 
diff --git a/docs/ko/fully_untranslated_files/Web_JavaScript_Reference_Lexical_grammar.md b/docs/ko/fully_untranslated_files/Web_JavaScript_Reference_Lexical_grammar.md
index 042d87ff86299e..34ad978e988b00 100644
--- a/docs/ko/fully_untranslated_files/Web_JavaScript_Reference_Lexical_grammar.md
+++ b/docs/ko/fully_untranslated_files/Web_JavaScript_Reference_Lexical_grammar.md
@@ -80,7 +80,7 @@ slug: Web/JavaScript/Reference/Lexical_grammar
 
 ## 개행 문자
 
-공백문자와 더불어, 개행 문자는 소스 본문의 가독성을 향상시킵니다. 하지만, 몇몇 상황에서 개행 문자는 코드 내부에 숨겨지기 때문에 자바스크립트 코드 실행에 영향을 미칩니다. 개행 문자는 자동 새미콜론 삽입([automatic semicolon insertion](#Automatic_semicolon_insertion)) 규칙에도 영향을 줍니다. 개행 문자는 표준 표현방식([regular expressions](/ko/docs/Web/JavaScript/Guide/Regular_Expressions))의 클래스인 \s로 매치됩니다.
+공백문자와 더불어, 개행 문자는 소스 본문의 가독성을 향상시킵니다. 하지만, 몇몇 상황에서 개행 문자는 코드 내부에 숨겨지기 때문에 JavaScript 코드 실행에 영향을 미칩니다. 개행 문자는 자동 새미콜론 삽입([automatic semicolon insertion](#Automatic_semicolon_insertion)) 규칙에도 영향을 줍니다. 개행 문자는 표준 표현방식([regular expressions](/ko/docs/Web/JavaScript/Guide/Regular_Expressions))의 클래스인 \s로 매치됩니다.
 
 아래의 유니코드 문자만이 ECMAScript에서 라인 종결자로 다뤄지며, 라인을 바꾸는 다른 문자들은 공백으로 생각하시면 됩니다(예를 들어, Next Line, NEL, U+0085는 공백으로 간주).
 
@@ -93,15 +93,15 @@ slug: Web/JavaScript/Reference/Lexical_grammar
 
 ## 주석
 
-주석은 힌트, 필기, 제안이나 주의할 점들을 자바스크립트 코드에 넣을 때 사용합니다. 이는 더 쉽게 읽고 이해할 수 있게 도와줍니다. 또한 특정 코드가 실행되지 않도록 막아주기도 합니다. 따라서 주석은 유용한 디버깅 도구라고도 할 수 있습니다.
+주석은 힌트, 필기, 제안이나 주의할 점들을 JavaScript 코드에 넣을 때 사용합니다. 이는 더 쉽게 읽고 이해할 수 있게 도와줍니다. 또한 특정 코드가 실행되지 않도록 막아주기도 합니다. 따라서 주석은 유용한 디버깅 도구라고도 할 수 있습니다.
 
-자바스크립트에는 코드 속에 주석을 쓰는 두 가지 방식이 있습니다.
+JavaScript에는 코드 속에 주석을 쓰는 두 가지 방식이 있습니다.
 
 첫 번째, '//'로 첨언하기입니다. 이는 아래의 예시처럼 같은 줄에 있는 모든 코드를 주석으로 바꿉니다.
 
 ```js
 function comment() {
-  // 자바스크립트의 각주 한 줄입니다.
+  // JavaScript의 각주 한 줄입니다.
   console.log("Hello world!");
 }
 comment();
@@ -113,7 +113,7 @@ comment();
 
 ```js
 function comment() {
-  /* 자바스크립트 각주 한 줄입니다. */
+  /* JavaScript 각주 한 줄입니다. */
   console.log("Hello world!");
 }
 comment();
diff --git a/files/es/learn/html/introduction_to_html/getting_started/index.md b/files/es/learn/html/introduction_to_html/getting_started/index.md
index bb650450aed0e3..b9e7791eb95681 100644
--- a/files/es/learn/html/introduction_to_html/getting_started/index.md
+++ b/files/es/learn/html/introduction_to_html/getting_started/index.md
@@ -1,72 +1,75 @@
 ---
-title: Empezar con HTML
+title: Primeros pasos con HTML
 slug: Learn/HTML/Introduction_to_HTML/Getting_started
+l10n:
+  sourceCommit: 194ea6cb5ddaf20e4f551cc93574be50b8b4f339
 ---
 
 {{LearnSidebar}}{{NextMenu("Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML", "Learn/HTML/Introduction_to_HTML")}}
 
-En este artículo vamos a exponer lo más básico del HTML. Para comenzar definiremos elementos, atributos y el resto de términos importantes que quizá ya te suenen y qué función cumplen dentro del lenguaje. También explica dónde encajan estos en HTML. Aprenderás cómo se estructuran los elementos HTML, cómo se estructura una página HTML típica y otras características básicas importantes del lenguaje. Por el camino, también iremos practicando con algo de HTML.
+En este artículo, cubrimos los conceptos básicos de HTML. Para empezar, este artículo define elementos, atributos y todos los demás términos importantes que puedas haber escuchado. También explica dónde encajan en HTML. Aprenderás cómo se estructuran los elementos HTML, cómo se estructura una página HTML típica y otras características importantes del lenguaje básico. ¡En el camino, también tendrás la oportunidad de jugar con HTML!
 
 
-      
+      
Prerrequisitos:Requisitos previos: - Conocimientos básicos de informática, - - tener instalado el software básico - - y conocimientos básicos de cómo - - trabajar con archivos - . + Conocimientos informáticos básicos, + software básico instalado, y conocimientos básicos de + trabajar con archivos.
Objetivo: - Familiarizarte con el lenguaje HTML, y adquirir algo de práctica - escribiendo unos pocos elementos HTML. + Para obtener una familiaridad básica con HTML y practicar la escritura de algunos + elementos HTML
-## ¿Qué es el HTML? +## ¿Qué es HTML? -{{Glossary("HTML")}} ("_Hypertext Markup Language_") no es un lenguaje de programación. Es un _lenguaje de marcado_ que le dice a los navegadores web cómo estructurar las páginas web que estás visitando. Puede ser tan complejo o tan simple como desee el desarrollador web. El HTML consiste en una serie de {{Glossary("Element", "elementos")}}, que puedes utilizar para encerrar, delimitar o _marcar_ diferentes partes del contenido para hacer que aparezcan de una cierta manera, o actúen de determinada forma. Las {{Glossary("Tag", "etiquetas")}} que delimitan un fragmento de contenido pueden hacer que dicho contenido enlace con otra página, ponga una palabra en cursiva, etcétera. Por ejemplo, dada la siguiente línea de contenido: +{{glossary("HTML")}} (HyperText Markup Language, por sus siglas en inglés) es un _lenguaje de marcado_ que indica a los navegadores web cómo estructurar las páginas web que visita. Puede ser tan complicado o tan simple como el desarrollador web quiera que sea. HTML consiste en una serie de {{glossary("Element", "elementos")}}, que utiliza para encerrar, envolver o _marcar_ diferentes partes del contenido para que aparezca o actúe de cierta manera. Las etiquetas pueden convertir el contenido en un hipervínculo para conectarse a otra página, poner palabras en cursiva, etc. Por ejemplo, considere la siguiente línea de texto: -``` +```plain Mi gato es muy gruñón ``` -Si queremos que la línea sea independiente de otras, podemos especificar que es un párrafo encerrándola con una etiqueta de elemento de párrafo ({{htmlelement("p")}}): +Si quisiéramos que el texto se mantuviera solo, podríamos especificar que es un párrafo encerrándolo en un elemento de párrafo ({{htmlelement("p")}}): ```html

Mi gato es muy gruñón

``` -> **Nota:** Las etiquetas en HTML no distinguen entre mayúsculas y minúsculas. Así que se pueden escribir tanto en mayúsculas como en minúsculas. Por ejemplo, una etiqueta {{htmlelement("title")}} se puede escribir como ``, `<TITLE>`, `<Title>`, `<TiTle>`, etc., y funcionará correctamente. La mejor práctica, sin embargo, es escribir todas las etiquetas en minúsculas para mantener la coherencia y legibilidad, entre otros motivos. +> **Nota:** Las etiquetas en HTML no distinguen entre mayúsculas y minúsculas. Esto significa que se pueden escribir en mayúsculas o minúsculas. Por ejemplo, una etiqueta {{htmlelement ("title")}} podría escribirse como `<title>`, `<TITLE>`, `<Title>`, `<TiTlE>`, etc., y funcionará. Sin embargo, es una buena práctica escribir todas las etiquetas en minúsculas para mayor coherencia y legibilidad. ## Anatomía de un elemento HTML -Exploremos un poco el elemento párrafo: +Exploremos más a fondo nuestro elemento de párrafo de la sección anterior: -![Anatomía de los elementos HTML](grumpy-cat-small.png) +![Un fragmento de código de ejemplo que demuestra la estructura de un elemento html.<p> Mi gato es muy gruñón</p>.](grumpy-cat-small.png) -Las principales partes de nuestro elemento son: +La anatomía de nuestro elemento es: -- La **etiqueta de apertura**: consiste en el nombre del elemento (en este caso, `p`), encerrado entre **paréntesis angulares** de apertura y cierre. Esta etiqueta de apertura marca dónde comienza el elemento o comienza a tener efecto. En este ejemplo, precede al comienzo del texto del párrafo. -- El **contenido**: Este es el contenido del elemento. En este ejemplo, es el texto del párrafo. -- La **etiqueta de cierre**: Es lo mismo que la etiqueta de apertura, excepto que incluye una barra diagonal antes del nombre del elemento. Esto indica dónde termina el elemento; en este caso, dónde finaliza el párrafo. No incluir una etiqueta de cierre es un error común de principiante, y puede conducir a extraños resultados. +- **La etiqueta de apertura:** Consiste en el nombre del elemento (en este ejemplo, _p_ para el párrafo), envuelto en corchetes angulares de apertura y cierre. Esta etiqueta de apertura marca dónde inicia o comienza a surtir efecto el elemento. En este ejemplo, precede al inicio del texto del párrafo. +- **El contenido:** Este es el contenido del elemento. En este ejemplo, es el texto del párrafo. +- **La etiqueta de cierre:** Esta es la misma que la etiqueta de apertura, excepto que incluye una barra diagonal delante del nombre del elemento. Esto marca donde termina el elemento. No incluir una etiqueta de cierre es un error común para principiantes que puede producir resultados peculiares. -El **elemento** lo conforman la etiqueta de apertura, seguida del contenido, seguido de la etiqueta de cierre. +El elemento es la etiqueta de apertura, seguida del contenido, seguida de la etiqueta de cierre. ### Aprendizaje activo: crear tu primer elemento HTML -Edita la siguiente línea en el área _Entrada_ envolviéndola con las etiquetas `<em>` y `</em>`. Para _abrir el elemento_, coloca la etiqueta de apertura `<em>` al principio de la línea. Para _cerrar el elemento_, coloca la etiqueta de cierre `</em>` al final de la línea. ¡Obtienes una línea en cursiva! Puedes ver tus cambios actualizados automáticamente en la caja de texto de _Salida_. +Edite la siguiente línea en el área "Código editable" envolviéndola con las etiquetas `<em>` y `</em>.` Para _abrir el elemento_, coloque la etiqueta de apertura `<em>` al comienzo de la línea. Para _cerrar el elemento_, coloque la etiqueta de cierre `</em>` al final de la línea. ¡Hacer esto debería darle formato de texto en cursiva a la línea! Consulta la actualización de tus cambios en vivo en el área de*Salida en vivo*. -Si te equivocas, siempre puedes volver al código anterior mediante el botón _Restablecer_. Si te quedas realmente atascado, pulsa el botón _Mostrar la solución_ para ver la solución. +Si comete un error, puede borrar su trabajo utilizando el botón*Restablecer*. Si te quedas realmente atascado, pulsa el botón*Mostrar solución* para ver la respuesta. ```html hidden <h2>Salida en vivo</h2> @@ -74,12 +77,12 @@ Si te equivocas, siempre puedes volver al código anterior mediante el botón _R <h2>Código editable</h2> <p class="a11y-label"> - Pulsa Esc para quitar el foco del área de código (Tab inserta un carácter de + Pulse Esc para alejar el foco del área de código (Tab inserta un carácter de tabulación). </p> <textarea id="code" class="playable-code" style="min-height: 100px;width: 95%"> -Este es mi texto. + Este es mi texto. </textarea> <div class="controls"> @@ -111,18 +114,21 @@ body { ``` ```js hidden -var textarea = document.getElementById("code"); -var reset = document.getElementById("reset"); -var solution = document.getElementById("solution"); -var output = document.querySelector(".output"); -var code = textarea.value; -var userEntry = textarea.value; +const textarea = document.getElementById("code"); +const reset = document.getElementById("reset"); +const solution = document.getElementById("solution"); +const output = document.querySelector(".output"); +const code = textarea.value; +let userEntry = textarea.value; function updateCode() { output.innerHTML = textarea.value; } -reset.addEventListener("click", function () { +const htmlSolution = "<em>Este es mi texto.</em>"; +let solutionEntry = htmlSolution; + +reset.addEventListener("click", () => { textarea.value = code; userEntry = textarea.value; solutionEntry = htmlSolution; @@ -130,7 +136,7 @@ reset.addEventListener("click", function () { updateCode(); }); -solution.addEventListener("click", function () { +solution.addEventListener("click", () => { if (solution.value === "Mostrar solución") { textarea.value = solutionEntry; solution.value = "Ocultar solución"; @@ -141,16 +147,12 @@ solution.addEventListener("click", function () { updateCode(); }); -var htmlSolution = "<em>Este es mi texto.</em>"; -var solutionEntry = htmlSolution; - textarea.addEventListener("input", updateCode); window.addEventListener("load", updateCode); -// captura la tecla de tabulación en el área de texto y en su lugar -// hace que se escriba una tabulación en la posición del cursor - -textarea.onkeydown = function (e) { +// detener la tabulación de la tecla tabulación fuera del área de texto y +// hacer que escriba una tabulación en la posición del cursor en su lugar +textarea.onkeydown = (e) => { if (e.keyCode === 9) { e.preventDefault(); insertAtCaret("\t"); @@ -162,27 +164,27 @@ textarea.onkeydown = function (e) { }; function insertAtCaret(text) { - var scrollPos = textarea.scrollTop; - var caretPos = textarea.selectionStart; + const scrollPos = textarea.scrollTop; + let caretPos = textarea.selectionStart; - var front = textarea.value.substring(0, caretPos); - var back = textarea.value.substring( + const front = textarea.value.substring(0, caretPos); + const back = textarea.value.substring( textarea.selectionEnd, textarea.value.length, ); textarea.value = front + text + back; - caretPos = caretPos + text.length; + caretPos += text.length; textarea.selectionStart = caretPos; textarea.selectionEnd = caretPos; textarea.focus(); textarea.scrollTop = scrollPos; } -// Actualiza el userCode guardado cada vez que el usuario actualiza el código del área de texto +// Actualizar el userCode guardado cada vez que el usuario actualice el código de área de texto -textarea.onkeyup = function () { +textarea.onkeyup = () => { // Solo queremos guardar el estado cuando se muestra el código de usuario, - // no es la solución, por lo que la solución no se guarda sobre el código del usuario + // no la solución, para que la solución no se guarde sobre el código de usuario if (solution.value === "Mostrar solución") { userEntry = textarea.value; } else { @@ -193,102 +195,79 @@ textarea.onkeyup = function () { }; ``` -{{ EmbedLiveSample('Código_reproducible', 700, 400, "", "", "hide-codepen-jsfiddle") }} +{{ EmbedLiveSample('Active_learning_creating_your_first_HTML_element', 700, 400, "", "") }} -### Elementos anidados +### Anidando elementos -Se pueden poner elementos dentro de otros elementos. Esto se llama **anidamiento**. Si quisiéramos decir que nuestro gato es **muy** gruñón, podríamos encerrar la palabra _muy_ en un elemento {{htmlelement("strong")}} para que aparezca destacada. +Los elementos se pueden colocar dentro de otros elementos. Esto se llama _anidamiento_. Si quisiéramos decir que nuestro gato está **muy** gruñón, podríamos envolver la palabra _muy_ en un elemento {{htmlelement("strong")}}, lo que significa que la palabra debe tener un formato de texto fuerte: ```html <p>Mi gato es <strong>muy</strong> gruñón.</p> ``` -Hay una forma correcta e incorrecta de anidar. En el ejemplo anterior, primero abrimos el elemento `p`, luego abrimos el elemento `strong`. Para un anidamiento adecuado, primero debemos cerrar el elemento `strong`, antes de cerrar el `p`. +Hay una forma correcta e incorrecta de anidar. En el ejemplo anterior, abrimos primero el elemento `p`, luego abrimos el elemento `strong`. Para una anidación adecuada, primero debemos cerrar el elemento `strong`, antes de cerrar `p`. El siguiente es un ejemplo de la forma _incorrecta_ de anidar: -```html example-bad +```html-nolint example-bad <p>Mi gato es <strong>muy gruñón.</p></strong> ``` -Los elementos tienen que abrirse y cerrarse correctamente para que estén claramente dentro o fuera el uno del otro. Con el tipo de superposición en el ejemplo anterior, el navegador tiene que adivinar tu intención. Este tipo de adivinanzas puede producir resultados inesperados. - -### Elementos de bloque y elementos en línea - -Hay dos categorías importantes de elementos en HTML — Estos son los elementos de bloque y los elementos en línea. - -- Los elementos de bloque forman un bloque visible en la página. Aparecerán en una línea nueva después de cualquier contenido anterior. Cualquier contenido que vaya después también aparecerá en una línea nueva. Los elementos a nivel de bloque suelen ser elementos estructurales de la página. Por ejemplo, un elemento a nivel de bloque puede representar encabezados, párrafos, listas, menús de navegación o pies de página. Un elemento a nivel de bloque no estaría anidado dentro de un elemento en línea, pero podría estar anidado dentro de otro elemento a nivel de bloque. -- Los elementos en línea están contenidos dentro de elementos de bloque y delimitan solo pequeñas partes del contenido del documento; (no párrafos enteros o agrupaciones de contenido) Un elemento en línea no hará que aparezca una nueva línea en el documento. Suele utilizarse con texto. Por ejemplo es el caso de un elemento {{htmlelement("a")}} (hipervínculo) o elementos de énfasis como {{htmlelement("em")}} o {{htmlelement("strong")}}. - -Considera el siguiente ejemplo: - -```html -<em>primero</em><em>segundo</em><em>tercero</em> - -<p>cuarto</p> -<p>quinto</p> -<p>sexto</p> -``` - -{{htmlelement("em")}} es un elemento en línea. Así, como puedes observar, los tres primeros elementos se sitúan en la misma línea, uno tras otro sin espacio entre ellos. Por otro lado, {{htmlelement("p")}} es un elemento a nivel de bloque. Cada elemento _p_ aparece en una nueva línea, con un espacio arriba y abajo. (El espaciado se debe al [estilo CSS](/es/docs/Learn/CSS/First_steps) predeterminado que el navegador aplica a los párrafos). - -{{ EmbedLiveSample('Elementos_de_bloque_y_elementos_en_línea', 700, 200, "", "") }} - -> **Nota:** HTML5 redefinió las categorías de elementos: consulta [Categorías de contenido de elementos](https://html.spec.whatwg.org/multipage/indices.html#element-content-categories). Si bien estas definiciones son más precisas y menos ambiguas que sus predecesoras, las nuevas definiciones son mucho más complicadas de entender que _block_ e _inline_ . Este artículo seguirá con estos dos términos. - -> **Nota:** Los términos «en bloque» (block) y «en línea» (inline), tal como se usan en este tema, no se deberían confundir con [los tipos de casillas de CSS](/es/docs/Learn/CSS/Introduction_to_CSS/Box_model#Types_of_CSS_boxes) que se conocen con el mismo nombre. Aunque de manera predeterminada están relacionados, el hecho de cambiar el tipo de aspecto visual del CSS no cambia la categoría del elemento ni afecta a aquellos elementos que pueda contener. Una de las razones por las que HTML5 abandonó el uso de estos términos fue para evitar este tipo de confusión. - -> **Nota:** Puedes encontrar referencias útiles que incluyen listas de elementos de bloque y elementos en línea. Consulta [Elementos en bloque](/es/docs/Glossary/Block-level_content) y [Elementos en línea](/es/docs/orphaned/Web/HTML/Inline_elements). +Las **etiquetas tienen que abrirse y cerrarse de manera que estén dentro o fuera la una de la otra**. Con el tipo de superposición en el ejemplo anterior, el navegador tiene que adivinar tu intención. Este tipo de adivinanzas puede dar lugar a resultados inesperados. ### Elementos vacíos -No todos los elementos siguen el patrón de etiqueta de apertura, contenido y etiqueta de cierre. Algunos elementos consisten solo en una etiqueta única, que se utiliza generalmente para insertar/incrustar algo en el documento en el lugar donde se le quiere incluir. Por ejemplo, el elemento {{htmlelement("img")}} inserta una imagen en la página: +No todos los elementos siguen el patrón de una etiqueta de apertura, contenido y una etiqueta de cierre. Algunos elementos consisten en una sola etiqueta, que normalmente se utiliza para insertar/incrustar algo en el documento. Dichos elementos se denominan {{glossary("void element", "elementos vacíos")}}. Por ejemplo, el elemento {{htmlelement ("img")}} incrusta un archivo de imagen en una página: ```html <img - src="https://raw.githubusercontent.com/mdn/beginner-html-site/gh-pages/images/firefox-icon.png" /> + src="https://raw.githubusercontent.com/mdn/beginner-html-site/gh-pages/images/firefox-icon.png" + alt="Icono de Firefox" /> ``` -Este texto mostrará lo siguiente en tu página: +Esto daría como resultado lo siguiente: -{{ EmbedLiveSample('Elementos_vacíos', 700, 300, "", "", "hide-codepen-jsfiddle") }} +{{ EmbedLiveSample('elementos_vacíos', 700, 300, "", "") }} -> **Nota:** Los elementos vacíos en ocasiones también se llaman elementos _nulos_ o _vanos_ (_void elements_). +> **Nota:** En HTML, no es necesario añadir un `/` al final de la etiqueta de un elemento vacío, por ejemplo: `<img src="images/cat.jpg" alt="cat" />`. Sin embargo, también es una sintaxis válida, y puede hacerlo cuando desee que su HTML sea XML válido. ## Atributos -Los elementos también pueden tener atributos. Los atributos tienen este aspecto: +Los elementos también pueden tener atributos. Los atributos se ven así: -![atributo html](grumpy-cat-attribute-small.png) +![etiqueta de párrafo con el atributo 'class="editor-note"' enfatizado](grumpy-cat-attribute-small.png) -Los atributos contienen información extra sobre el elemento que no se mostrará en el contenido. En este caso, el atributo `class` asigna al elemento un identificador que se puede utilizar para dotarlo de información de estilo. +Los atributos contienen información adicional sobre el elemento que no aparecerá en el contenido. En este ejemplo, el atributo **`class`** es un nombre de identificación utilizado para identificar el elemento con información de estilo. -Un atributo debería tener: +Un atributo debe tener: -- Un espacio entre este y el nombre del elemento. (Para un elemento con más de un atributo, los atributos también deben estar separados por espacios). -- El nombre del atributo, seguido por un signo igual. -- Un valor del atributo, rodeado de comillas de apertura y cierre. +- Un espacio entre él y el nombre del elemento. (Para un elemento con más de un atributo, los atributos también deben estar separados por espacios). +- El nombre del atributo, seguido de un signo igual. +- Un valor de atributo, envuelto con comillas de apertura y cierre. -### Aprendizaje activo: Añadir atributos a un elemento +### Aprendizaje activo: añadir atributos a un elemento -Otro ejemplo de un elemento es {{htmlelement("a")}}. Esto significa _ancla_. Una ancla puede convertir el texto que encierra en un hipervínculo. Las anclas pueden tener varios atributos, pero varios son como sigue: +El elemento `<img>` puede tomar una serie de atributos, que incluyen: -- `href` - - : El valor de este atributo indica la dirección web a la que se quiere que apunte el enlace, que será hacia donde nos lleve el navegador cuando se haga clic sobre el elemento. Por ejemplo, `href="https://www.mozilla.org/"`. -- `title` - - : El atributo `title` añade información adicional sobre el enlace, como puede ser el título de la página que vinculas. Por ejemplo, `title="La página de inicio de Mozilla"`. Esta información aparecerá cuando se le pase el ratón por encima. -- `target` - - : El atributo `target` especifica el contexto de navegación que va a usar para mostrar el enlace. Por ejemplo, `target="_blank"` abrirá el enlace en una nueva pestaña. Si quieres mostrar el enlace en la pestaña activa, simplemente omite este atributo. +- `src` + - : El atributo `src` es un atributo **requerido** que especifica la ubicación de la imagen. Por ejemplo: `src="https://raw.githubusercontent.com/mdn/beginner-html-site/gh-pages/images/firefox-icon.png"`. +- `alt` + - : El atributo `alt` especifica una descripción de texto de la imagen. Por ejemplo: `alt="El icono de Firefox"`. +- `width` + - : El atributo `width` especifica el ancho de la imagen con la unidad en píxeles. Por ejemplo: `width="300"`. +- `height` + - : El atributo `height` especifica la altura de la imagen con la unidad en píxeles. Por ejemplo: `height="300"`. -Edita la línea de abajo en el área de _Entrada_ para convertirlo en un enlace a tu sitio web favorito. +Edita la siguiente línea en el área del _Input_ para convertirla en una imagen. -1. Añade el elemento `<a>`. -2. Añade el atributo `href` y el atributo `title`. -3. Especifica el atributo `target` para abrir el enlace en una nueva pestaña. +1. Encuentra tu imagen favorita en línea, haz clic con el botón derecho y pulsa _Copiar enlace/dirección de imagen_. +2. De vuelta en el área de abajo, añade el atributo `src` y rellénalo con el enlace del paso 1. +3. Establece el atributo `alt`. +4. Añade los atributos `width` y `height`. -Los cambios se actualizarán inmediatamente en la zona de _Salida_. Deberías ver un enlace que mostrará el contenido del atributo `title` cuando pases el ratón encima, y que te llevará a la dirección web indicada por el atributo `href` cuando hagas clic. Recuerda que debes incluir un espacio entre el nombre del elemento y cada atributo. +Podrás ver los cambios en vivo en el área de _Salida_. -Si te equivocas, siempre puedes restablecer el código anterior pulsando el botón _Restablecer_. Si te quedas realmente atascado, pulsa el botón _Mostrar la solución_ para ver la solución. +Si comete un error, siempre puede restablecerlo utilizando el botón _Restablecer_. Si te quedas realmente atascado, pulsa el botón _Mostrar solución_ para ver la respuesta. ```html hidden <h2>Salida en vivo</h2> @@ -297,12 +276,12 @@ Si te equivocas, siempre puedes restablecer el código anterior pulsando el bot <h2>Código editable</h2> <p class="a11y-label"> - Pulsa Esc para quitar el foco del área de código (Tab inserta un carácter de + Pulse Esc para alejar el foco del área de código (Tab inserta un carácter de tabulación). </p> <textarea id="code" class="input" style="min-height: 100px;width: 95%"> -&lt;p&gt;Un enlace a mi sitio web favorito.&lt;/p&gt; +<img alt="Debería ser una imagen" > </textarea> <div class="playable-buttons"> @@ -334,18 +313,22 @@ body { ``` ```js hidden -var textarea = document.getElementById("code"); -var reset = document.getElementById("reset"); -var solution = document.getElementById("solution"); -var output = document.querySelector(".output"); -var code = textarea.value; -var userEntry = textarea.value; +const textarea = document.getElementById("code"); +const reset = document.getElementById("reset"); +const solution = document.getElementById("solution"); +const output = document.querySelector(".output"); +const code = textarea.value; +let userEntry = textarea.value; function updateCode() { output.innerHTML = textarea.value; } -reset.addEventListener("click", function () { +const htmlSolution = + '<img src="https://raw.githubusercontent.com/mdn/beginner-html-site/gh-pages/images/firefox-icon.png" alt="Icono de Firefox" width="100" height="100" />'; +let solutionEntry = htmlSolution; + +reset.addEventListener("click", () => { textarea.value = code; userEntry = textarea.value; solutionEntry = htmlSolution; @@ -353,7 +336,7 @@ reset.addEventListener("click", function () { updateCode(); }); -solution.addEventListener("click", function () { +solution.addEventListener("click", () => { if (solution.value === "Mostrar solución") { textarea.value = solutionEntry; solution.value = "Ocultar solución"; @@ -364,17 +347,13 @@ solution.addEventListener("click", function () { updateCode(); }); -var htmlSolution = - '<p>Un enlace a mi <a href="https://www.mozilla.org/" title="La página de inicio de Mozilla" target="_blank">sitio web favorito</a>.</p>'; -var solutionEntry = htmlSolution; - textarea.addEventListener("input", updateCode); window.addEventListener("load", updateCode); -// captura la tecla de tabulación en el área de texto y en su lugar -// hace que se escriba una tabulación en la posición del cursor +// detener la tabulación de la tecla tabulación fuera del área de texto y +// hacer que escriba una tabulación en la posición del cursor en su lugar -textarea.onkeydown = function (e) { +textarea.onkeydown = (e) => { if (e.keyCode === 9) { e.preventDefault(); insertAtCaret("\t"); @@ -386,27 +365,27 @@ textarea.onkeydown = function (e) { }; function insertAtCaret(text) { - var scrollPos = textarea.scrollTop; - var caretPos = textarea.selectionStart; + const scrollPos = textarea.scrollTop; + let caretPos = textarea.selectionStart; - var front = textarea.value.substring(0, caretPos); - var back = textarea.value.substring( + const front = textarea.value.substring(0, caretPos); + const back = textarea.value.substring( textarea.selectionEnd, textarea.value.length, ); textarea.value = front + text + back; - caretPos = caretPos + text.length; + caretPos += text.length; textarea.selectionStart = caretPos; textarea.selectionEnd = caretPos; textarea.focus(); textarea.scrollTop = scrollPos; } -// Actualiza el userCode guardado cada vez que el usuario actualiza el código del área de texto +// Actualizar el userCode guardado cada vez que el usuario actualice el código de área de texto -textarea.onkeyup = function () { +textarea.onkeyup = () => { // Solo queremos guardar el estado cuando se muestra el código de usuario, - // no es la solución, por lo que la solución no se guarda sobre el código del usuario + // no la solución, para que la solución no se guarde sobre el código de usuario if (solution.value === "Mostrar solución") { userEntry = textarea.value; } else { @@ -417,20 +396,20 @@ textarea.onkeyup = function () { }; ``` -{{ EmbedLiveSample('Código_reproducible_2', 700, 400, "", "", "hide-codepen-jsfiddle") }} +{{ EmbedLiveSample('Active_learning_Adding_attributes_to_an_element', 700, 400, "", "") }} ### Atributos booleanos -En ocasiones puedes ver atributos escritos sin valor. Esto está permitido. Estos se denominan atributos booleanos. Los atributos booleanos solo pueden tener un valor, que generalmente es el mismo que el nombre del atributo. Por ejemplo, considera el atributo [`disabled`](/es/docs/Web/HTML/Element/input#disabled), que puedes asignar a los elementos de entrada del formulario. (Usa esto para _deshabilitar_ los elementos de entrada del formulario para que el usuario no pueda realizar entradas. Los elementos desactivados suelen tener una apariencia atenuada). Por ejemplo: +A veces verás atributos escritos sin valores. Esto es totalmente aceptable. Estos se llaman atributos booleanos. Los atributos booleanos solo pueden tener un valor, que generalmente es el mismo que el nombre del atributo. Por ejemplo, considere el atributo [`disabled`](/es/docs/Web/HTML/Element/input#disabled), que puede asignar a los elementos de entrada de formulario. (Utiliza esto para _deshabilitar_ los elementos de entrada del formulario para que el usuario no pueda realizar entradas. Los elementos deshabilitados suelen tener un aspecto grisáceo.) Por ejemplo: -```bash -<input type="text" disabled="disabled"> +```html +<input type="text" disabled="disabled" /> ``` -De manera abreviada, también es posible escribirlo como se describe a continuación (además, se ha incluido un elemento de entrada de formulario no desactivado como referencia, para dar una idea más precisa de lo que sucede): +Como abreviatura, es aceptable escribir esto de la siguiente manera: ```html -<!-- el uso del atributo deshabilitado evita que el usuario final introduzca texto en el cuadro de entrada --> +<!-- el uso del atributo deshabilitado impide que el usuario final introduzca texto en el cuadro de entrada --> <input type="text" disabled /> <!-- se permite la entrada de texto, ya que no contiene el atributo deshabilitado --> @@ -439,73 +418,71 @@ De manera abreviada, también es posible escribirlo como se describe a continuac Como referencia, el ejemplo anterior también incluye un elemento de entrada de formulario no deshabilitado. El HTML del ejemplo anterior produce este resultado: -{{ EmbedLiveSample('Atributos_booleanos', 700, 100, "", "", "hide-codepen-jsfiddle") }} +{{ EmbedLiveSample('Atributos_booleanos', 700, 100, "", "") }} -### Omitir comillas en valores de atributos +### Omitir comillas en torno a los valores de atributo -Cuando observas diferentes páginas web, puedes encontrarte con todo tipo de estilos de etiquetado extraños, que incluyen valores de atributos sin comillas. Esto se permite en ciertas circunstancias, pero interrumpirá la edición en otras. Por ejemplo, si volvemos a revisar el ejemplo del enlace, sería posible escribir una versión básica con solo el atributo `href`, así: +Si observa el código de muchos otros sitios, es posible que encuentre una serie de estilos de marcado extraños, incluidos los valores de atributos sin comillas. Esto está permitido en ciertas circunstancias, pero también puede romper su margen de beneficio en otras circunstancias. El elemento en el fragmento de código a continuación, `<a>`, se llama ancla. Los anclajes encierran texto y los convierten en enlaces. El atributo `href` especifica la dirección web a la que apunta el enlace. Puedes escribir esta versión básica a continuación con _solo_ el atributo `href`, así: ```html -<a href=https://www.mozilla.org/>mi sitio web favorito</a> +<a href=https://www.mozilla.org/>sitio web favorito</a> ``` -Sin embargo, las cosas no funcionarán cuando a este estilo se añada el atributo `title`: +Los anclajes también pueden tener un atributo `title`, una descripción de la página vinculada. Sin embargo, tan pronto como añadimos el `title` de la misma manera que el atributo `href` hay problemas: -```html example-bad -<a href=https://www.mozilla.org/ title=La pagina de Mozilla>mi sitio web favorito</a> +```html-nolint example-bad +<a href=https://www.mozilla.org/ title=Pagina de Mozilla>sitio web favorito</a> ``` -En este punto el navegador interpretará mal el cambio y pensará que el atributo `title` corresponde a tres atributos: un atributo `title` con el valor _La_ y dos atributos booleanos: `Mozilla` y `homepage`. ¡Obviamente, esta no es la intensión! Causará errores o comportamientos inesperados, como puedes ver en el ejemplo en vivo a continuación. ¡Intenta colocar el cursor sobre el enlace para ver el texto del título! +Como se ha escrito anteriormente, el navegador malinterpreta el marcado, confundiendo el atributo `title` con tres atributos: un atributo title con el valor `The`, y dos atributos booleanos, `Mozilla` y `homepage`. ¡Obviamente, esto no es la intención! Causará errores o comportamientos inesperados, como puede ver en el ejemplo en vivo a continuación. ¡Intenta pasar el cursor sobre el enlace para ver el texto del título! -{{ EmbedLiveSample('Omitir_comillas_en_valores_de_atributos', 700, 100, "", "", "hide-codepen-jsfiddle") }} +{{ EmbedLiveSample('Omitir_comillas_en_torno_a_los_valores_de_atributo', 700, 100, "", "") }} -Incluye **siempre** las comillas de atributos. Evita tales problemas y da como resultado un código más legible. +Incluya siempre las comillas de los atributos. Evita tales problemas y da como resultado un código más legible. ### ¿Comillas simples o dobles? -En este artículo todos los atributos se han incluido en comillas dobles. Sin embargo, se pueden ver comillas simples en algún código HTML. Es una cuestión de estilo. Puedes elegir libremente cuál prefieres. Ambas líneas de código son equivalentes: +En este artículo, también notarás que los atributos están entre comillas dobles. Sin embargo, es posible que veas comillas simples en algún código HTML. Es una cuestión de estilo. Puedes elegir libremente cuál prefieres. Ambas opciones son equivalentes: -```html -<a href="http://www.ejemplo.com">Un enlace a mi ejemplo.</a> +```html-nolint +<a href='https://www.example.com'>Un enlace a mi ejemplo.</a> -<a href="http://www.ejemplo.com">Un enlace a mi ejemplo.</a> +<a href="https://www.example.com">Un enlace a mi ejemplo.</a> ``` -Asegúrate de no mezclar ambos tipos de comillas. El siguiente ejemplo muestra un tipo de mezcla de comillas que saldrá mal: +Asegúrate de no mezclar comillas simples y comillas dobles. Este ejemplo (a continuación) muestra una especie de mezcla de comillas que saldrá mal: -```html example-bad -<a href="http://www.ejemplo.com'>Un enlace a mi ejemplo.</a> +```html-nolint example-bad +<a href="https://www.example.com'>Un enlace a mi ejemplo.</a> ``` -Si utilizas un tipo de comillas en tu documento HTML, puedes incluir el otro tipo de comillas para tus valores de atributo sin que esto te cause problemas: +Sin embargo, si utilizas un tipo de comilla, puedes incluir el otro tipo de comilla _dentro_ tus valores de atributo: ```html -<a href="http://www.ejemplo.com" title="¿A que es 'divertido'" - >Un enlace a mi ejemplo.</a -> +<a href="https://www.example.com" title="¿No es 'esto' divertido?"> + Un enlace a mi ejemplo. +</a> ``` -Sin embargo, si deseas anidar unas comillas dentro de otras del mismo tipo (ya sea simples o dobles), tendrás que utilizar entidades HTML para las comillas. Por ejemplo, el siguiente código no va a funcionar: +Para usar comillas dentro de otras comillas del mismo tipo (comillas simples o comillas dobles), use [entidades HTML](#entity_references_including_special_characters_in_html). Por ejemplo, esto se romperá: -```html example-bad -<a href='http://www.ejemplo.com' title='¿A que es 'divertido'?'>Un enlace a mi ejemplo.</a> +```html-nolint example-bad +<a href="https://www.example.com" title="Una referencia "interesante"">Un enlace a mi ejemplo.</a> ``` -Así que tendrás que hacer esto: +En su lugar, debe hacer lo siguiente: -```html -<a href="http://www.ejemplo.com" title="¿A que es 'divertido'?" - >Un enlace a mi ejemplo.</a -> +```html-nolint +<a href="https://www.example.com" title="Una referencia "interesante"">Un enlace a mi ejemplo.</a> ``` ## Anatomía de un documento HTML -Los elementos HTML no son muy útiles por sí mismos. Ahora veremos cómo combinar los elementos individuales para formar una página HTML completa: +Los elementos HTML individualmente no son muy útiles por sí solos. A continuación, examinemos cómo se combinan los elementos para formar una página HTML completa: ```html <!doctype html> -<html> +<html lang="es"> <head> <meta charset="utf-8" /> <title>Mi página de prueba @@ -518,44 +495,42 @@ Los elementos HTML no son muy útiles por sí mismos. Ahora veremos cómo combin Aquí tenemos: -1. ``: El elemento _doctype_. En sus inicios, cuando el HTML llevaba poco tiempo (alrededor de 1991-1992), los _doctypes_ servían como enlaces al conjunto de reglas que la página HTML debía seguir para que fuera considerado buen HTML. Un elemento _doctype_ de aquella época podía parecerse a esto: +1. ``: El tipo de documento. Cuando HTML era joven (1991-1992), los doctype estaban destinados a actuar como enlaces a un conjunto de reglas que la página HTML tenía que seguir para ser considerada un buen HTML. Los doctypes solían parecerse a algo como esto: ```html ``` - En la actualidad se ignora y se considera un legado histórico que hay que incluir para que todo funcione correctamente. `` es la secuencia de caracteres más corta que se acepta como elemento _doctype_ válido. Eso es lo único que realmente necesitas saber. - -2. ``: El elemento ``. Este elemento envuelve todo el contenido de la página. A veces se lo conoce como el elemento raíz. -3. ``: El elemento `<{{htmlelement("head")}}>` (cabecera). Este elemento actúa como contenedor para todos los parámetros que quieras incluir en el documento HTML que _no serán_ visibles a los visitantes de la página. Incluye cosas como palabras clave y la descripción de la página que quieras mostrar en los resultados de búsqueda, así como la hoja de estilo para formatear nuestro contenido, declaraciones de codificación de caracteres y más. Aprenderás más acerca de esto en el siguiente artículo de la serie. -4. ``: Este elemento establece que tu documento HTML usará la codificación UTF-8, que incluye la gran mayoría de caracteres de todos los idiomas humanos escritos. En resumen: puede gestionar cualquier contenido textual que pongas en tu documento. No hay razón para no configurar este valor y te puede ayudar a evitar problemas más adelante. -5. ``: El elemento {{htmlelement("title")}}. Este establece el título de la página, que es el título que aparece en la pestaña del navegador en la que se carga la página. El título de la página también se utiliza para describir la página cuando se marca como favorita. -6. ``: El elemento ``. Contiene todo el contenido que quieres mostrar a los usuarios cuando visitan tu página, ya sea texto, imágenes, vídeos, juegos, pistas de audio reproducibles o cualquier otra cosa. + Más recientemente, el doctype es un artefacto histórico que debe incluirse para que todo lo demás funcione correctamente. `` es la cadena más corta de caracteres que cuenta como un tipo de documento válido. ¡Eso es todo lo que necesitas saber! -### Aprendizaje activo: Añadir algunas características a un documento HTML +2. ``: El elemento {{htmlelement("html")}}. Este elemento envuelve todo el contenido de la página. A veces se le conoce como el elemento raíz. +3. ``: El elemento {{htmlelement("head")}}. Este elemento actúa como un contenedor para todo lo que desea incluir en la página HTML, **que no es el contenido** que la página mostrará a los espectadores. Esto incluye palabras clave y una descripción de la página que aparecería en los resultados de búsqueda, CSS para dar estilo al contenido, declaraciones de conjuntos de caracteres y más. Aprenderás más sobre esto en el próximo artículo de la serie. +4. ``: El elemento {{htmlelement("meta")}}. Este elemento representa metadatos que no pueden ser representados por otros elementos HTML relacionados con metadatos, como {{htmlelement("base")}}, {{htmlelement("link")}}, {{htmlelement("script")}}, {{htmlelement("style")}} o {{htmlelement("title")}}. El atributo [`charset`](/es/docs/Web/HTML/Element/meta#charset) especifica la codificación de caracteres para su documento como UTF-8, que incluye la mayoría de los caracteres de la gran mayoría de los lenguajes humanos escritos. Con esta configuración, la página ahora puede manejar cualquier contenido textual que pueda contener. No hay razón para no configurar esto, y puede ayudar a evitar algunos problemas más adelante. +5. ``: El elemento {{htmlelement("title")}}. Esto establece el título de la página, que es el título que aparece en la pestaña del navegador en la que se carga la página. El título de la página también se utiliza para describir la página cuando está en marcadores. +6. ``: El elemento {{htmlelement("body")}}. Contiene _todo_ el contenido que se muestra en la página, incluidos texto, imágenes, vídeos, juegos, pistas de audio reproducibles o cualquier otra cosa. -Si quieres escribir algo de HTML en tu ordenador local para experimentar, puedes: +### Aprendizaje activo: añadir algunas funciones a un documento HTML -1. Copiar el ejemplo de la página HTML del punto anterior. -2. Crear un archivo nuevo en un editor de texto. -3. Pegar el código en el nuevo archivo de texto. -4. Guardar el archivo como `index.html`. +Si quieres experimentar con escribir algo de HTML en tu ordenador local, puedes: -> **Nota:** También puedes encontrar esta plantilla básica de HTML en el [repositorio GitHub del Área MDN Learning](https://github.com/mdn/learning-area/blob/master/html/introduction-to-html/getting-started/index.html). +1. Copie el ejemplo de página HTML listado anteriormente. +2. Crea un nuevo archivo en tu editor de texto. +3. Pega el código en el nuevo archivo de texto. +4. Guarde el archivo como `index.html`. -Ahora puedes abrir este archivo en un navegador web para ver cómo se ve el código renderizado. Edita el código y actualiza el navegador para ver cuál es el resultado. En principio se verá algo así: +> **Nota:** También puedes encontrar esta plantilla HTML básica en el [repositorio de GitHub del área de aprendizaje de MDN](https://github.com/mdn/learning-area/blob/main/html/introduction-to-html/getting-started/index.html). -![Una sencilla página HTML que dice esta es mi página](template-screenshot.png) +Ahora puede abrir este archivo en un navegador web para ver cómo se ve el código renderizado. Edita el código y actualiza el navegador para ver cuál es el resultado. Inicialmente, la página se ve así: -En este ejercicio, puedes editar el código en tu ordenador como se indica arriba, o puedes editarlo en la ventana editable que tienes a continuación (la ventana editable representa solo el contenido del elemento {{htmlelement("body")}}, en este caso). Intenta reproducir los siguientes pasos: +![Una simple página HTML que dice Esta es mi página](template-screenshot.png)En este ejercicio, puedes editar el código localmente en tu ordenador, como se describió anteriormente, o puedes editarlo en la ventana de muestra a continuación (la ventana de muestra editable representa solo el contenido del elemento {{htmlelement("body")}}, en este caso). Mejora tus habilidades implementando las siguientes tareas: -- Justo debajo de la etiqueta de apertura {{htmlelement("body")}}, añade un título principal para el documento. Este deberá estar dentro de una etiqueta de apertura `

` y una etiqueta de cierre `

`. -- Edita el contenido del párrafo e incluye algún texto sobre algo que te interese. -- Pon las palabras importantes dentro de etiquetas `` de apertura y `` de cierre para que destaquen en negrita. -- Añade un enlace a tu párrafo, como se ha explicado [anteriormente en este mismo artículo](#active_learning_adding_attributes_to_an_element). -- Agrega una imagen a tu documento. Colócala debajo del párrafo, como [se explicó anteriormente en el artículo](#empty_elements). Ganarás puntos extra si consigues enlazar a una imagen diferente (de tu propio ordenador o de cualquier otro lugar de la web). +- Justo debajo de la etiqueta de apertura del elemento {{htmlelement("body")}}, añade un título principal para el documento. Esto debe envolverse dentro de una etiqueta `

` de apertura y `

` de cierre. +- Edita el contenido del párrafo para incluir texto sobre un tema que te parezca interesante. +- Haz que las palabras importantes se destaquen en negrita envolviéndolas dentro de una etiqueta `` de apertura y `` de cierre. +- Añade un enlace a tu párrafo, como [se explicó anteriormente en el artículo](#active_learning_adding_attributes_to_an_element). +- Añade una imagen a tu documento. Colócalo debajo del párrafo, como [se explicó anteriormente en el artículo](#void_elements). Gana puntos de bonificación si consigues vincular a una imagen diferente (ya sea localmente en tu ordenador o en algún otro lugar de la web). -Si te equivocas, siempre puedes restablecer el código anterior pulsando el botón _Restablecer_. Si te quedas realmente atascado, pulsa el botón _Mostrar la solución_ para ver la solución. +Si comete un error, siempre puede restablecerlo utilizando el botón _Restablecer_. Si te quedas realmente atascado, pulsa el botón _Mostrar solución_ para ver la respuesta. ```html hidden

Salida en vivo

@@ -564,12 +539,12 @@ Si te equivocas, siempre puedes restablecer el código anterior pulsando el bot

Código editable

- Pulsa Esc para quitar el foco del área de código (Tab inserta un carácter de + Pulse Esc para alejar el foco del área de código (Tab inserta un carácter de tabulación).

@@ -609,18 +584,22 @@ body { ``` ```js hidden -var textarea = document.getElementById("code"); -var reset = document.getElementById("reset"); -var solution = document.getElementById("solution"); -var output = document.querySelector(".output"); -var code = textarea.value; -var userEntry = textarea.value; +const textarea = document.getElementById("code"); +const reset = document.getElementById("reset"); +const solution = document.getElementById("solution"); +const output = document.querySelector(".output"); +const code = textarea.value; +let userEntry = textarea.value; function updateCode() { output.innerHTML = textarea.value; } -reset.addEventListener("click", function () { +const htmlSolution = + '

Algo de música

Disfruto mucho tocando la batería. Uno de mis bateristas favoritos es Neal Peart, que toca en la banda Rush. Mi álbum favorito de Rush es actualmente Moving Pictures.

Rush Moving Pictures album cover'; +let solutionEntry = htmlSolution; + +reset.addEventListener("click", () => { textarea.value = code; userEntry = textarea.value; solutionEntry = htmlSolution; @@ -628,7 +607,7 @@ reset.addEventListener("click", function () { updateCode(); }); -solution.addEventListener("click", function () { +solution.addEventListener("click", () => { if (solution.value === "Mostrar solución") { textarea.value = solutionEntry; solution.value = "Ocultar solución"; @@ -639,17 +618,13 @@ solution.addEventListener("click", function () { updateCode(); }); -var htmlSolution = - '

Un poco de música

Realmente disfruto tocar la batería. Uno de mis bateristas favoritos es Neal Peart, que toca en la banda Rush. Mi álbum favorito de Rush actualmente es Fotografías de la película.

'; -var solutionEntry = htmlSolution; - textarea.addEventListener("input", updateCode); window.addEventListener("load", updateCode); -// captura la tecla de tabulación en el área de texto y en su lugar -// hace que se escriba una tabulación en la posición del cursor +// detener la tabulación de la tecla tabulación fuera del área de texto y +// hacer que escriba una tabulación en la posición del cursor en su lugar -textarea.onkeydown = function (e) { +textarea.onkeydown = (e) => { if (e.keyCode === 9) { e.preventDefault(); insertAtCaret("\t"); @@ -661,27 +636,26 @@ textarea.onkeydown = function (e) { }; function insertAtCaret(text) { - var scrollPos = textarea.scrollTop; - var caretPos = textarea.selectionStart; + const scrollPos = textarea.scrollTop; + let caretPos = textarea.selectionStart; - var front = textarea.value.substring(0, caretPos); - var back = textarea.value.substring( + const front = textarea.value.substring(0, caretPos); + const back = textarea.value.substring( textarea.selectionEnd, textarea.value.length, ); textarea.value = front + text + back; - caretPos = caretPos + text.length; + caretPos += text.length; textarea.selectionStart = caretPos; textarea.selectionEnd = caretPos; textarea.focus(); textarea.scrollTop = scrollPos; } -// Actualiza el userCode guardado cada vez que el usuario actualiza el código del área de texto - -textarea.onkeyup = function () { +// Actualizar el userCode guardado cada vez que el usuario actualice el código de área de texto +textarea.onkeyup = () => { // Solo queremos guardar el estado cuando se muestra el código de usuario, - // no es la solución, por lo que la solución no se guarda sobre el código del usuario + // no la solución, para que la solución no se guarde sobre el código de usuario if (solution.value === "Mostrar solución") { userEntry = textarea.value; } else { @@ -692,78 +666,99 @@ textarea.onkeyup = function () { }; ``` -{{ EmbedLiveSample('Código_reproducible_3', 700, 600, "", "", "hide-codepen-jsfiddle") }} +{{ EmbedLiveSample('Active_learning_Adding_some_features_to_an_HTML_document', 700, 500) }} -### Los espacios en blanco en HTML +### Espacios en blanco en HTML -En los ejemplos anteriores se han incluido espacios en blanco y saltos de línea en el código. Esto realmente no es necesario. Los dos siguientes fragmentos de código son equivalentes: +En los ejemplos anteriores, es posible que hayas notado que se incluyen muchos espacios en blanco en el código. Este paso es opcional. Estos dos fragmentos de código son equivalentes: -```html -

Los perros son tontos.

+```html-nolint +

Los perros son tontos.

-

Los perros son tontos.

+

Los perros + son + tontos.

``` -No importa cuántos espacios en blanco se utilicen (incluye tanto caracteres de espacio como saltos de línea) el intérprete de HTML reduce cada secuencia de espacio en blanco a un único espacio al interpretar el código. Entonces, ¿por qué utilizar espacios en blanco? La respuesta está en la legibilidad. +No importa cuánto espacio en blanco utilice dentro del contenido del elemento HTML (que puede incluir uno o más caracteres de espacio, o también saltos de línea), el analizador HTML reduce cada secuencia de espacio en blanco a un solo espacio al representar el código. Entonces, ¿por qué usar tanto espacio en blanco? La respuesta es la legibilidad. -Es más fácil comprender lo que está sucediendo en tu código si lo tienes bien formateado. En nuestro HTML cada elemento anidado está sangrado dos espacios más con respecto al exterior. Depende de ti qué estilo de formato utilizas (cuántos espacios para cada nivel de sangría, por ejemplo) pero debes plantearte el uso de algún tipo de formato. +Puede ser más fácil entender lo que está pasando en tu código si lo tienes bien formateado. En nuestro HTML tenemos cada elemento anidado indentado por dos espacios más que el que está dentro. Depende de usted elegir el estilo de formato (cuántos espacios para cada nivel de indentación, por ejemplo), pero debe considerar formatearlo. -## Referencias a entidades: Inclusión de caracteres especiales en HTML +Echemos un vistazo a cómo el navegador representa los dos párrafos anteriores con y sin espacios en blanco: -En HTML, los caracteres `<`, `>`,`"`,`'` y `&` son caracteres especiales. Forman parte de la sintaxis HTML. Entonces, ¿cómo incluye uno de estos caracteres especiales en tu texto? Por ejemplo, si deseas utilizar un signo comercial o menor que, y no hacer que se interprete como código. +{{ EmbedLiveSample('Whitespace_in_HTML', 700, 100) }} -Haces esto con referencias de caracteres. Estos son códigos especiales que representan caracteres, para ser usados en estas circunstancias exactas. Cada referencia de caracter comienza con un signo de ampersand (&) y finaliza con un punto y coma (;). +> **Nota:** El acceso a [innerHTML](/es/docs/Web/API/Element/innerHTML) de los elementos de JavaScript mantendrá intacto todo el espacio en blanco. +> Esto puede arrojar resultados inesperados si el navegador recorta el espacio en blanco. -| Caracter literal | Equivalente de referencia de caracteres | -| ---------------- | --------------------------------------- | -| < | \< | -| > | \> | -| " | \" | -| ' | \' | -| & | \& | +```js +const noWhitespace = document.getElementById("noWhitespace").innerHTML; +console.log(noWhitespace); +// "Los perros son tontos". -El equivalente de referencia de caracter podría recordarse fácilmente porque el texto que utiliza se puede ver como menor que para '\<' , cita para ' \" ' y de manera similar para otros. Para obtener más información sobre la referencia de entidad, consulta [Anexo:Referencias a entidades de caracteres XML y HTML](https://es.wikipedia.org/wiki/Anexo:Referencias_a_entidades_de_caracteres_XML_y_HTML) en (Wikipedia). +const whitespace = document.getElementById("whitespace").innerHTML; +console.log(whitespace); +// "Los perros +// son +// tontos." +``` -Considera los dos siguientes párrafos: +## Referencias de entidades: Incluir caracteres especiales en HTML -```html -

En HTML, defines un párrafo con el elemento

-

.

+En HTML, los caracteres `<`, `>`, `"`, `'` y `&` son caracteres especiales. Son partes de la sintaxis HTML en sí. Entonces, ¿cómo incluyes uno de estos caracteres especiales en tu texto? Por ejemplo, si desea usar un signo ampersand (&) o menor que, y no interpretarlo como código. + +Haces esto con referencias de caracteres. Estos son códigos especiales que representan caracteres, para ser utilizados en estas circunstancias exactas. Cada referencia de carácter comienza con un ampersand (&) y termina con un punto y coma (;). + +| Carácter literal | Referencia de carácter equivalente | +| ---------------- | ---------------------------------- | +| < | `<` | +| > | `>` | +| " | `"` | +| ' | `'` | +| & | `&` | -

En HTML, defines un párrafo con el elemento <p>.

+El equivalente de referencia de carácter podría recordarse fácilmente porque el texto que utiliza puede verse como _menor que (less than, en inglés)_ para '\<', _comilla (quot, en inglés)_ para '\"' y de manera similar para otros. Para obtener más información sobre las referencias de entidades, consulta [Lista de referencias de entidades de caracteres XML y HTML](https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references) (Wikipedia). + +En el siguiente ejemplo, hay dos párrafos: + +```html-nolint +

En HTML, se define un párrafo utilizando el elemento

.

+ +

En HTML, se define un párrafo utilizando el elemento <p>.

``` -En la salida en vivo de abajo, puedes ver que el primer párrafo salió mal. El navegador interpreta la segunda instancia de `

` como el inicio de un nuevo párrafo. El segundo párrafo se ve bien porque hemos remplazado `<` y `>` por sus referencias correspondientes. +En la salida en vivo a continuación, puede ver que el primer párrafo ha salido mal. El navegador interpreta la segunda instancia de `

` como comenzar un nuevo párrafo. El segundo párrafo se ve bien porque tiene corchetes angulares con referencias de caracteres. -{{ EmbedLiveSample('Referencias_a_entidades_Inclusión_de_caracteres_especiales_en_HTML', 700, 200) }} +{{ EmbedLiveSample('Entity_references_Including_special_characters_in_HTML', 700, 200, "", "") }} -> **Nota:** En la Wikipedia se puede localizar un listado de todas las referencias de entidades de caracteres HTML disponibles: [Anexo:Referencias a entidades de caracteres XML y HTML](https://es.wikipedia.org/wiki/Anexo:Referencias_a_entidades_de_caracteres_XML_y_HTML). Observa que no necesitas usar ninguna referencia de entidad más para ningún otro de estos símbolos porque los navegadores modernos gestionan estos símbolos correctamente siempre y cuando en tu HTML hayas [establecido la codificación de el juego de caracteres universal UTF-8](/es/docs/Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML#specifying_your_document's_character_encoding). +> **Nota:** No es necesario usar referencias de entidad para ningún otro símbolo, ya que los navegadores modernos manejarán bien los símbolos reales siempre que la [codificación de caracteres de tu HTML esté configurada en UTF-8](/es/docs/Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML#specifying_your_documents_character_encoding). -## Comentarios HTML +## Comentarios en HTML -En HTML hay un mecanismo para escribir comentarios en el código. Los comentarios son ignorados por el navegador y, por tanto, son invisibles para el usuario. El propósito de los comentarios es permitirte incluir notas en el código para explicar tu lógica o codificación. Esto es muy útil si regresas a un código base después de estar ausente el tiempo suficiente como para no recordarlo por completo. Del mismo modo, los comentarios son invaluables ya que diferentes personas están realizando cambios y actualizaciones. +HTML tiene un mecanismo para escribir comentarios en el código. Los navegadores ignoran los comentarios, lo que hace que los comentarios sean invisibles para el usuario. El propósito de los comentarios es permitirle incluir notas en el código para explicar su lógica o codificación. Esto es muy útil si vuelve a una base de código después de estar ausente el tiempo suficiente para no recordarlo por completo. Del mismo modo, los comentarios son invaluables ya que diferentes personas están haciendo cambios y actualizaciones. -Para convertir en un comentario una sección de contenido de tu archivo HTML, debes delimitarlo con los marcadores especiales ``. Por ejemplo: +Para escribir un comentario en HTML, envuélvalo en los marcadores especiales ``. Por ejemplo: ```html -

No soy un comentario

+

No estoy dentro de un comentario

- + ``` -Como puedes ver a continuación, el primer párrafo aparece, pero el segundo no. +Como puede ver a continuación, solo se muestra el primer párrafo en la salida en vivo. -{{ EmbedLiveSample('Comentarios_HTML', 700, 100, "", "", "hide-codepen-jsfiddle") }} +{{ EmbedLiveSample('HTML_comments', 700, 100, "", "") }} ## Resumen -Has llegado al final del artículo. Espero que hayas disfrutado del recorrido los conceptos básicos del HTML. -En este punto ya deberías entender el lenguaje, cómo funciona en un nivel básico y deberías poder escribir algunos elementos y atributos. También deberías poder escribir algunos elementos y atributos. Los artículos posteriores de este módulo profundizan en algunos de los temas aquí presentados, además de presentar otros conceptos del lenguaje. +¡Has llegado al final del artículo! Esperamos que hayas disfrutado de tu recorrido por los conceptos básicos de HTML. + +En este punto, debes entender cómo se ve HTML y cómo funciona a un nivel básico. También deberías poder escribir algunos elementos y atributos. Los artículos posteriores de este módulo profundizan en algunos de los temas introducidos aquí, así como en la presentación de otros conceptos del lenguaje. -> **Nota:** En este punto, a medida que empieces a aprender más sobre HTML, es posible que también desees comenzar a explorar los conceptos básicos de las Hojas de estilo en cascada (_Cascading style sheets_) o [CSS](/es/docs/Learn/CSS). CSS, es el lenguaje utilizado para estilizar páginas web. (por ejemplo, cambiar fuentes o colores, o alterar el diseño de la página) HTML y CSS funcionan bien juntos, como pronto descubrirás. +- A medida que comiences a aprender más sobre HTML, considera aprender los conceptos básicos de CSS (hojas de estilo en cascada). [CSS](/es/docs/Learn/CSS) es el lenguaje utilizado para dar estilo a las páginas web, como cambiar fuentes o colores o alterar el diseño de la página. HTML y CSS funcionan bien juntos, como pronto descubrirás. -## Ve también +## Vease también -- [Aplicación de color a elementos HTML mediante CSS](/es/docs/Web/HTML/Applying_color) +- [Aplicar color a elementos HTML usando CSS](/es/docs/Web/CSS/CSS_colors/Applying_color) {{NextMenu("Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML", "Learn/HTML/Introduction_to_HTML")}} diff --git a/files/es/learn/javascript/building_blocks/looping_code/index.md b/files/es/learn/javascript/building_blocks/looping_code/index.md index 94a1e9e1c1cb04..2e25e6bb4869fb 100644 --- a/files/es/learn/javascript/building_blocks/looping_code/index.md +++ b/files/es/learn/javascript/building_blocks/looping_code/index.md @@ -1,499 +1,637 @@ --- -title: Bucles +title: Código de bucle slug: Learn/JavaScript/Building_blocks/Looping_code +l10n: + sourceCommit: e3faa375b0179de77a5eff00074e3d168a0a904c --- {{LearnSidebar}}{{PreviousMenuNext("Learn/JavaScript/Building_blocks/conditionals","Learn/JavaScript/Building_blocks/Functions", "Learn/JavaScript/Building_blocks")}} -Los lenguajes de programación son muy útiles para completar rápidamente tareas repetitivas, desde múltimples cálculos básicos hasta cualquier otra situación en donde tengas un montón de elementos de trabajo similares que completar. Aquí vamos a ver las estructuras de bucles disponibles en JavaScript que pueden manejar tales necesidades. +Los lenguajes de programación son muy útiles para completar rápidamente tareas repetitivas, desde múltiples cálculos básicos hasta casi cualquier otra situación en la que tenga que completar muchos elementos de trabajo similares. Aquí veremos las estructuras de bucle disponibles en JavaScript que manejan tales necesidades. -| Prerequisitos: | Conocimientos básicos de computación, entendimiento básico de HTML y CSS, [JavaScript first steps](/es/docs/Learn/JavaScript/First_steps). | -| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | -| Objetivo: | Entender cómo usar bucles en JavaScript. | + + + + + + + + + + + +
Prerrequisitos: + Conocimientos básicos de informática, una comprensión básica de HTML y CSS, + Primeros pasos de JavaScript . +
Objetivo:Comprender cómo usar bucles en JavaScript.
-## Mantente en el Bucle +## ¿Por qué son útiles los bucles? -Bucles, bucles, bucles. Además de ser conocidos como un cereal de desayuno popular, montañas rusas y producción músical, también son un concepto muy importante en programación. Los bucles de programación están relacionados con todo lo referente a hacer una misma cosa una y otra vez — que se denomina como **iteración** en el idioma de programación. +Los bucles se tratan de hacer lo mismo una y otra vez. A menudo, el código será ligeramente diferente cada vez que dure el bucle, o se ejecutará el mismo código pero con diferentes variables. -Consideremos el caso de un agricultor que se asegura de tener suficiente comida para alimentar a su familia durante la semana. Podría usar el siguiente bucle para lograr esto: +### Ejemplo de código de bucles -![](loop_js-02-farm.png) +Supongamos que queremos dibujar 100 círculos aleatorios en un elemento {{htmlelement("canvas")}} (pulse el botón _Actualizar_ para ejecutar el ejemplo una y otra vez para ver diferentes conjuntos aleatorios): -Un bucle cuenta con una o más de las siguientes características: +```html hidden + +``` -- Un **contador,** que se inicia con un determinado valor — este será el valor del punto inicial del bucle ("Inicio: No tengo comida",mirar arriba). -- Una **condicion de salida**, que será el criterio bajo el cual, el bucle se romperá — normalmente un contador que alcanza un determinado valor. Aquí se ilustra como "¿Tengo suficiente comida?", arriba. Digamos que son necesarias 10 porciones de comida para alimentar a su familia. -- Un **iterador,** que generalmente incrementa el valor del contador en una cantidad pequeña a cada paso del bucle, hasta que alcanza la condición de salida. No hemos ilustrado esto de manera explícita arriba, pero podríamos pensar que el granjero está recolectando 2 porciones de comida cada hora. Después de cada hora, la cantidad de comida recolectada se incrementa en dos, y comprueba si tiene suficiente comida. Si alcanza los 10 puntos (la condición de salida), puede parar la recolecta e irse para casa. +```css hidden +html { + width: 100%; + height: inherit; + background: #ddd; +} -En {{glossary("pseudocódigo")}},esto se vería como sigue: +canvas { + display: block; +} -``` -bucle(comida = 0; comidaNecesaria = 10) { - if (comida = comidaNecesaria) { - salida bucle; - // Tenemos suficiente comida; vamonos para casa - } else { - comida += 2; // Pasar una hora recogiendo 2 más de comida - // Comenzar el bucle de nuevo - } +body { + margin: 0; +} + +button { + position: absolute; + top: 5px; + left: 5px; } ``` -Así que la cantidad necesaria de comida se establece en 10, y la cantidad incial del granjero en 0. En cada iteración del bucle comprobamos si la cantidad de comida del granjero es mayor o igual a la cantidad que necesita. Si lo es, podemos salir del bucle. Si no, el granjero se pasará una hora más recogiendo dos porciones de comida, y el bucle arrancará de nuevo. +{{ EmbedLiveSample('ejemplo_de_código_de_bucles', '100%', 400) }} -### ¿Por qué molestarse? +Este es el código JavaScript que implementa este ejemplo: -En este punto, probablemente entiendas los conceptos de alto nivel que hay detrás de los bucles, pero probablemente estés pensando "OK, fantástico, pero ¿cómo me ayuda esto a escribir un mejor codigo JavaScript?". Como dijimos antes, **los bucles tienen que ver con hacer lo mismo una y otra vez**, lo cual es bueno para **completar rápidamente tareas repetitivas**. +```js +const btn = document.querySelector("button"); +const canvas = document.querySelector("canvas"); +const ctx = canvas.getContext("2d"); + +document.addEventListener("DOMContentLoaded", () => { + canvas.width = document.documentElement.clientWidth; + canvas.height = document.documentElement.clientHeight; +}); -Muchas veces, el código será ligeramente diferente en cada iteracción sucesiva del bucle, lo que significa que puedes completar una carga completa de tareas que son similares, pero ligeramente diferentes — si tienes muchos calculos diferentes que hacer, quieres hacer cada uno de ellos, ¡no el mismo una y otra vez! +function random(number) { + return Math.floor(Math.random() * number); +} -Vamos a ver un ejemplo para ilustrar perfectamente por qué los bucles son tan útiles. Digamos que queremos dibujar 100 círculos aleatorios en un elemento {{htmlelement("canvas")}} (presiona el botón _Update_ para ejecutar el ejemplo una y otra vez y ver diferentes configuraciones aleatorias): +function draw() { + ctx.clearRect(0, 0, canvas.width, canvas.height); + for (let i = 0; i < 100; i++) { + ctx.beginPath(); + ctx.fillStyle = "rgba(255,0,0,0.5)"; + ctx.arc( + random(canvas.width), + random(canvas.height), + random(50), + 0, + 2 * Math.PI, + ); + ctx.fill(); + } +} -```html hidden - - - - - Random canvas circles - - - - - - - - - - -``` - -{{ EmbedLiveSample('Hidden_code', '100%', 400, "", "", "hide-codepen-jsfiddle") }} - -No tienes que entender todo el código por ahora, pero vamos a echar un vistazo a la parte de código que dibuja los 100 círculos: +btn.addEventListener("click", draw); +``` + +### Con y sin bucles + +No tienes que entender todo el código por ahora, pero veamos la parte del código que realmente dibuja los 100 círculos: ```js -for (var i = 0; i < 100; i++) { +for (let i = 0; i < 100; i++) { ctx.beginPath(); ctx.fillStyle = "rgba(255,0,0,0.5)"; - ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI); + ctx.arc( + random(canvas.width), + random(canvas.height), + random(50), + 0, + 2 * Math.PI, + ); ctx.fill(); } ``` -Debes quedarte con la idea básica. — utilizamos un bucle para ejecutar 100 iteracciones de este código, cada una de las cuales dibuja un círculo en una posición aleatoria de la página. La cantidad de código necesario sería el mismo si dibujáramos 100, 1000, o 10,000 círculos. Solo necesitamos cambiar un número. +- `random(x)`, definido anteriormente en el código, devuelve un número entero entre `0` y `x-1`. -Si no usáramos un bucle aquí, tendríamos que repetir el siguiente código por cada círculo que quisiéramos dibujar: +Deberías tener la idea básica: estamos usando un bucle para ejecutar 100 iteraciones de este código, cada una de las cuales dibuja un círculo en una posición aleatoria en la página. +La cantidad de código necesaria sería la misma si estuviéramos dibujando 100 círculos, 1000 o 10.000. +Solo un número tiene que cambiar. + +Si no estuviéramos usando un bucle aquí, tendríamos que repetir el siguiente código para cada círculo que quisiéramos dibujar: ```js ctx.beginPath(); ctx.fillStyle = "rgba(255,0,0,0.5)"; -ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI); +ctx.arc( + random(canvas.width), + random(canvas.height), + random(50), + 0, + 2 * Math.PI, +); ctx.fill(); ``` -Esto sería muy aburrido y difícil de mantener de forma rápida. Los bucles son realmente lo mejor. +Esto sería muy aburrido y difícil de mantener. + +## Recorriendo una colección -## El bucle estándar `for` +La mayoría de las veces, cuando usas un bucle, tendrás una colección de artículos y querrás hacer algo con cada artículo. -Exploremos algunos constructores de bucles específicos. El primero, que usarás la mayoría de las veces, es el bucle [for](/es/docs/Web/JavaScript/Referencia/Sentencias/for) - este tiene la siguiente sintaxis: +Un tipo de colección es el {{jsxref("Array","Arreglo")}}, que conocimos en el capítulo de [Arreglos](/es/docs/Learn/JavaScript/First_steps/Arrays) de este curso. +Pero también hay otras colecciones en JavaScript, como {{jsxref ("Set")}} y {{jsxref("Map")}}. +### El bucle for...of + +La herramienta básica para recorrer una colección es el bucle {{jsxref("statements/for...of","for...of")}}: + +```js +const cats = ["Leopardo", "Serval", "Jaguar", "Tigre", "Caracal", "León"]; + +for (const cat of cats) { + console.log(cat); +} ``` -for (inicializador; condición de salida; expresión final) { + +En este ejemplo, `for (const cat of cats)` dice: + +1. Dada la colección `cats`, consigue el primer artículo de la colección. +2. Asignarlo a la variable `cat` y luego ejecutar el código entre las llaves `{}`. +3. Obtén el siguiente elemento y repite (2) hasta que hayas llegado al final de la colección. + +### map() y filter() + +JavaScript también tiene bucles más especializados para colecciones, y mencionaremos dos de ellos aquí. + +Puede usar `map()` para hacer algo con cada elemento de una colección y crear una nueva colección que contenga los elementos modificados: + +```js +function toUpper(string) { + return string.toUpperCase(); +} + +const cats = ["Leopardo", "Serval", "Jaguar", "Tigre", "Caracal", "León"]; + +const upperCats = cats.map(toUpper); + +console.log(upperCats); +// [ "LEOPARDO", "SERVAL", "JAGUAR", "TIGRE", "CARACAL", "LEÓN" ] +``` + +Aquí pasamos una función a {{jsxref("Array.prototype.map()","cats.map()")}}, y `map()` llama a la función una vez por cada elemento de la matriz, pasando el elemento. A continuación, añade el valor devuelto de cada llamada de función a un nuevo arreglo y, finalmente, devuelve el nuevo arreglo. En este caso, la función que proporcionamos convierte el elemento en mayúsculas, por lo que la matriz resultante contiene todos nuestros gatos en mayúsculas: + +```js-nolint +[ "LEOPARDO", "SERVAL", "JAGUAR", "TIGRE", "CARACAL", "LEÓN" ] +``` + +Puede usar {{jsxref("Array.prototype.filter()","filter()")}} para probar cada elemento de una colección y crear una nueva colección que contenga solo elementos que coincidan: + +```js +function lCat(cat) { + return cat.startsWith("L"); +} + +const cats = ["Leopardo", "Serval", "Jaguar", "Tigre", "Caracal", "León"]; + +const filtered = cats.filter(lCat); + +console.log(filtrado); +// [ "Leopardo", "León" ] +``` + +Esto se parece mucho a `map()`, excepto que la función que pasamos devuelve un [booleano](/es/docs/Learn/JavaScript/First_steps/Variables#booleans): si devuelve `true`, entonces el elemento se incluye en el nuevo arreglo. +Nuestra función prueba que el elemento comienza con la letra "L", por lo que el resultado es una matriz que contiene solo gatos cuyos nombres comienzan con "L": + +```js-nolint +[ "Leopardo", "León" ] +``` + +Tenga en cuenta que `map()` y `filter()` se usan a menudo con _expresiones de funciones_, que aprenderemos en el módulo [Functions](/es/docs/Learn/JavaScript/Building_blocks/Functions). +Usando expresiones de función podríamos reescribir el ejemplo anterior para que sea mucho más compacto: + +```js +const cats = ["Leopardo", "Serval", "Jaguar", "Tigre", "Caracal", "León"]; + +const filter = cats.filter((cat) => cat.startsWith("L")); +console.log(filtrado); +// [ "Leopardo", "León" ] +``` + +## El bucle estándar for + +En el ejemplo anterior de "círculos de dibujo", no tiene una colección de elementos para recorrer: realmente solo desea ejecutar el mismo código 100 veces. +En un caso como ese, debes usar el bucle {{jsxref("statements/for","for")}}. +Tiene la siguiente sintaxis: + +```js-nolint +for (inicializador; condición; expresión-final) { // código a ejecutar } ``` Aquí tenemos: -1. La palabra reservada `for`, seguida por algunos paréntesis. -2. Dentro de los paréntesis tenemos tres ítems, separados por punto y coma (;): +1. La palabra clave `for`, seguida de algunos paréntesis. +2. Dentro de los paréntesis tenemos tres ítems, separados por punto y coma: + + 1. Un **inicializador**: generalmente es una variable establecida en un número, que se incrementa para contar el número de veces que se ha ejecutado el bucle. + También se denomina a veces **variable de contador**. + 2. Una **condición**: define cuándo el bucle debe dejar de funcionar. + Esta es generalmente una expresión que presenta un operador de comparación, una prueba para ver si se ha cumplido la condición de salida. + 3. Una **expresión-final**: siempre se evalúa (o ejecuta) cada vez que el bucle ha pasado por una iteración completa. + Por lo general, sirve para incrementar (o en algunos casos disminuir) la variable contadora, para acercarla al punto en que la condición ya no es `true`. - 1. Un **inicializador** - Este es usualmente una variable con un número asignado, que aumenta el número de veces que el bucle ha sijo ejecutado. También se le llama **contador** o **variable de conteo**. - 2. Una **condición de salida** - como se mencionó previamente, ésta define cuando el bucle debería detenerse. Generalmente es una expresión que contiene un operador de comparación, una prueba para verificar ue la condición de término o salida ha sido cumplida. - 3. Una **expresión final** - que es siempre evaluada o ejecutada cada vez que el bucle ha completado una iteración. Usualmente sirve para modificar al contador (incrementando su valor o algunas veces disminuyendolo), para aproximarse a la condición de salida. +3. Algunas llaves que contienen un bloque de código: este código se ejecutará cada vez que el bucle se repita. -3. Algunos corchetes curvos que contienen un bloque de código - este código se ejecutará cada vez que se repita el bucle. +### Cálculo de cuadrados -Observa un ejemplo real para poder entender esto más claramente. +Veamos un ejemplo real para que podamos visualizar lo que estos hacen con mayor claridad. + +```html oculto + + +

+```
 
 ```js
-var cats = ["Bill", "Jeff", "Pete", "Biggles", "Jasmin"];
-var info = "My cats are called ";
-var para = document.querySelector("p");
+const results = document.querySelector("#results");
 
-for (var i = 0; i < cats.length; i++) {
-  info += cats[i] + ", ";
+function calculate() {
+  for (let i = 1; i < 10; i++) {
+    const newResult = `${i} x ${i} = ${i * i}`;
+    results.textContent += `${newResult}\n`;
+  }
+  results.textContent += "\n¡Finalizado!";
 }
 
-para.textContent = info;
+const calculateBtn = document.querySelector("#calculate");
+const clearBtn = document.querySelector("#clear");
+
+calculateBtn.addEventListener("click", calculate);
+clearBtn.addEventListener("click", () => (results.textContent = ""));
 ```
 
 Esto nos da el siguiente resultado:
 
-```html hidden
-
-
-  
-    
-    Basic for loop example
-    
-  
-  
-    

+{{ EmbedLiveSample('cálculo_de_cuadrados', '100%', 250) }} - - - +1. `let i = 1`: la variable del contador, `i`, comienza en `1`. Tenga en cuenta que tenemos que usar `let` para el contador, porque lo estamos reasignando cada vez que damos la vuelta al bucle. +2. `i < 10`: sigue dando la vuelta al bucle mientras `i` sea menor que `10`. +3. `i++`: añade uno a `i` cada vez que recorras el bucle. + +Dentro del bucle, calculamos el cuadrado del valor actual de `i`, es decir: `i * i`. Creamos una cadena que expresa el cálculo que realizamos y el resultado, y añadimos esta cadena al texto de salida. También añadimos `\n`, por lo que la siguiente cadena que añadamos comenzará en una nueva línea. De manera que: + +1. Durante la primera ejecución, `i = 1`, por lo que añadiremos `1 x 1 = 1`. +2. Durante la segunda ejecución, `i = 2`, por lo que añadiremos `2 x 2 = 4`. +3. Y así sucesivamente... +4. Cuando `i` sea igual a `10`, dejaremos de ejecutar el bucle y pasaremos directamente al siguiente código debajo del bucle, imprimiendo el mensaje `¡Finalizado!` en una nueva línea. + +### Recorriendo colecciones con un bucle for + +Puede usar un bucle `for` para iterar a través de una colección, en lugar de un bucle `for...of`. + +Echemos un vistazo de nuevo a nuestro ejemplo anterior "for...of": + +```js +const cats = ["Leopardo", "Serval", "Jaguar", "Tigre", "Caracal", "León"]; + +for (const cat of cats) { + console.log(cat); +} ``` -{{ EmbedLiveSample('Hidden_code_2', '100%', 60, "", "", "hide-codepen-jsfiddle") }} +Podríamos reescribir ese código así: -> **Nota:** Puedes encontrar este [ejemplo de código en GitHub](https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/basic-for.html) también (además puedes [verlo ejecutar en vivo](http://mdn.github.io/learning-area/javascript/building-blocks/loops/basic-for.html)). +```js +const cats = ["Leopardo", "Serval", "Jaguar", "Tigre", "Caracal", "León"]; -Esto muestra un bucle siendo usado para iterar sobre los elementos de un arreglo (matriz), y hacer algo con cada uno de ellos - un patrón muy común en JavaScript. Aquí: +for (let i = 0; i < cats.length; i++) { + console.log(cats[i]); +} +``` + +En este bucle, comenzamos `i` en `0` y nos detenemos cuando `i` alcanza la longitud del arreglo. +Luego, dentro del bucle, estamos usando `i` para acceder a cada elemento del arreglo a su vez. + +Esto funciona muy bien, y en las primeras versiones de JavaScript, `for...of` no existía, por lo que esta era la forma estándar de iterar a través de un arreglo. +Sin embargo, ofrece más posibilidades de introducir errores en tu código. Por ejemplo: + +- puede comenzar `i` en `1`, olvidando que el primer índice del arreglo es cero, no 1. +- puede detenerse en `i <= cats.length`, olvidando que el último índice de matriz está en `length - 1`. -1. El iterador, `i`, inicia en `0` (`var i = 0`). -2. Se le ha dicho que debe ejecutarse hasta que no sea menor que la longitud del arreglo `cats`. Esto es importante - la condición de salida muestra la condicion bajo la cual el bucle seguirá iterando. Así, en este caso, mientras `i < cats.length` sea verdadero, el bucle seguirá ejecutándose. -3. Dentro del bucle, concatenamos el elemento del bucle actual (`cats[i]` es `cats[lo que sea i en ese momento]`) junto con una coma y un espacio, al final de la variable `info`. Así: +Por razones como esta, generalmente es mejor usar `for...of` si puedes. - 1. Durante la primera ejecución, `i = 0`, así `cats[0] + ', '` se concatenará con la información ("Bill, "). - 2. Durante la segunda ejecución, `i = 1`, así `cats[1] + ', '` agregará el siguiente nombre ("Jeff, "). - 3. Y así sucesivamente. Después de cada vez que se ejecute el bucle, se incrementará en 1 el valod de i (`i++`), entonces el proceso comenzará de nuevo. +A veces todavía necesitas usar un bucle `for` para iterar a través de un arreglo. +Por ejemplo, en el siguiente código queremos registrar un mensaje que enumere a nuestros gatos: + +```js +const cats = ["Pete", "Biggles", "Jasmine"]; + +let myFavoriteCats = "Mis gatos se llaman "; + +for (const cat of cats) { + myFavoriteCats += `${cat}, `; +} -4. Cuando `i` sea igual a `cats.length`, el bucle se detendrá, y el navegador se moverá al siguiente segmento de código bajo el bucle. +console.log(myFavoriteCats); // "Mis gatos se llaman Pete, Biggles, Jasmine, " +``` -> **Nota:** Hemos programado la condición de salidad como `i < cats.length`, y no como `i <= cats.length`, porque los computadores cuentan desde 0, no 1 - inicializamos la variable i en 0, para llegar a `i = 4` (el índice del último elemento del arreglo). `cats.length` responde 5, ya que existen 5 elementos en el arreglo, pero no queremos que i = 5, dado que respondería `undefined` para el último elemento (no existe un elemento en el arreglo con un índice 5). for the last item (there is no array item with an index of 5). Por ello, queremos llegar a 1 menos que `cats.length` (`i <`), que no es lo mismo que `cats.length` (`i <=`). +La oración de salida final no está muy bien formada: -> **Nota:** Un error común con la condición de salida es utilizar el comparador "igual a" (`===`) en vez de "menor o igual a" (`<=`). Si queremos que nuestro bucle se ejecute hasta que `i = 5`, la condición de salida debería ser `i <= cats.length`. Si la declaramos `i === cats.length`, el bucle no debería ejecutarse , porque `i` no es igual a `5` en la primera iteración del bucle, por lo que debería detenerse inmediatamente. +```plain +Mis gatos se llaman Pete, Biggles, Jasmine, +``` -Un pequeño problema que se presenta es que la frase de salida final no está muy bien formada: +Preferiríamos que manejara al último gato de manera diferente, así: -> My cats are called Bill, Jeff, Pete, Biggles, Jasmin, +```plain +Mis gatos se llaman Pete, Biggles y Jasmine. +``` -Idealmente querríamos cambiar la concatenacion al final de la última iteracion del bucle, así no tendríamos una coma en el final de la frase. Bueno, no hay problema - podemos insertar un condicional dentro de nuestro bucle para solucionar este caso especial: +Pero para hacer esto necesitamos saber cuándo estamos en la iteración final del bucle, y para hacerlo podemos usar un bucle `for` y examinar el valor de `i`: ```js -for (var i = 0; i < cats.length; i++) { +const cats = ["Pete", "Biggles", "Jasmine"]; + +let myFavoriteCats = "Mis gatos se llaman "; + +for (let i = 0; i < cats.length; i++) { if (i === cats.length - 1) { - info += "and " + cats[i] + "."; + // Estamos al final del arreglo + myFavoriteCats += `y ${cats[i]}.`; } else { - info += cats[i] + ", "; + myFavoriteCats += `${cats[i]}, `; } } -``` - -> **Nota:** You can find this [example code on GitHub](https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/basic-for-improved.html) too (also [see it running live](http://mdn.github.io/learning-area/javascript/building-blocks/loops/basic-for-improved.html)). -> **Advertencia:** **Importante**: Con `for` - como con todos los bucles - debes estar seguro de que el inicializador es repetido hasta que eventualemtne alcance la condición de salida. Si no, el bucle seguirá repitiéndose indefinidamente, y puede que el navegador lo fuerce a detenerse o se interrumpa. Esto se denomina **bucle infinito**. +console.log(myFavoriteCats); // "Mis gatos se llaman Pete, Biggles y Jasmine." +``` -## Salir de un bucle con `break` +## Saliendo de bucles con break -Si deseas salir de un bucle antes de que se hayan completado todas las iteraciones, puedes usar la declaración [break](/es/docs/Web/JavaScript/Referencia/Sentencias/break). Ya la vimos en el artículo previo cuando revisamos la declaración [switch](/es/docs/Web/JavaScript/Referencia/Sentencias/switch) - cuando un caso en una declaración `switch` coincide con la expresión de entrada, la declaración `break` inmediatamente sale de la declaración `switch` y avanza al código que se encuentra después. +Si desea salir de un bucle antes de que se hayan completado todas las iteraciones, puede usar la instrucción [break](/es/docs/Web/JavaScript/Reference/Statements/break). +Ya vimos esto en el artículo anterior cuando analizamos las [sentencias switch](/es/docs/Learn/JavaScript/Building_blocks/conditionals#switch_statements): cuando se cumple un caso en una sentencia switch que coincide con la expresión de entrada, la sentencia `break` sale inmediatamente de la sentencia switch y pasa al código después de ella. -Ocurre lo mismo con los bucles - una declaración `break` saldrá inmediatamente del bucle y hará que el navegador siga con el código que sigue después. +Es lo mismo con los bucles: una instrucción `break` saldrá inmediatamente del bucle y hará que el navegador pase a cualquier código que lo siga. -Digamos que queremos buscar a través de un arreglo de contactos y números telefónicos y retornar sólo el número que queríamos encontrar. primero, un simple HTML - un {{htmlelement("input")}} de texto que nos permita ingresar un nombre para buscar, un elemento {{htmlelement("button")}} para enviar la búsqueda, y un elemento {{htmlelement("p")}} para mostrar el resultado: +Digamos que queríamos buscar a través de una serie de contactos y números de teléfono y devolver solo el número que queríamos encontrar. +Primero, un HTML simple: un {{htmlelement("input")}} de texto que nos permite ingresar un nombre para buscar, un elemento {{htmlelement ("button")}} para enviar una búsqueda y un elemento {{htmlelement("p")}} para mostrar los resultados en: ```html - + - +

``` -Ahora en el JavaScript: +Ahora pasemos a JavaScript: ```js -var contacts = [ +const contacts = [ "Chris:2232322", "Sarah:3453456", "Bill:7654322", "Mary:9998769", "Dianne:9384975", ]; -var para = document.querySelector("p"); -var input = document.querySelector("input"); -var btn = document.querySelector("button"); +const para = document.querySelector("p"); +const input = document.querySelector("input"); +const btn = document.querySelector("button"); -btn.addEventListener("click", function () { - var searchName = input.value; +btn.addEventListener("click", () => { + const searchName = input.value.toLowerCase(); input.value = ""; input.focus(); - for (var i = 0; i < contacts.length; i++) { - var splitContact = contacts[i].split(":"); - if (splitContact[0] === searchName) { - para.textContent = - splitContact[0] + "'s number is " + splitContact[1] + "."; + para.textContent = ""; + for (const contact of contacts) { + const splitContact = contact.split(":"); + if (splitContact[0].toLowerCase() === searchName) { + para.textContent = `El número de ${splitContact[0]} es ${splitContact[1]}.`; break; - } else { - para.textContent = "Contact not found."; } } + if (para.textContent === "") { + para.textContent = "Contacto no encontrado."; + } }); ``` -{{ EmbedLiveSample('Hidden_code_3', '100%', 100, "", "", "hide-codepen-jsfiddle") }} - -1. First of all we have some variable definitions — we have an array of contact information, with each item being a string containing a name and phone number separated by a colon. -2. Next, we attach an event listener to the button (`btn`), so that when it is pressed, some code is run to perform the search and return the results. -3. We store the value entered into the text input in a variable called `searchName`, before then emptying the text input and focusing it again, ready for the next search. -4. Now onto the interesting part, the for loop: +{{ EmbedLiveSample('saliendo_de_bucles_con_break', '100%', 100) }} - 1. We start the counter at `0`, run the loop until the counter is no longer less than `contacts.length`, and increment `i` by 1 after each iteration of the loop. - 2. Inside the loop we first split the current contact (`contacts[i]`) at the colon character, and store the resulting two values in an array called `splitContact`. - 3. We then use a conditional statement to test whether `splitContact[0]` (the contact's name) is equal to the inputted `searchName`. If it is, we enter a string into the paragraph to report what the contact's number is, and use `break` to end the loop. +1. En primer lugar, tenemos algunas definiciones de variables: tenemos una variedad de información de contacto, y cada elemento es una cadena que contiene un nombre y un número de teléfono separados por dos puntos. +2. A continuación, adjuntamos un detector de eventos al botón (`btn`) para que cuando se pulse se ejecute algún código para realizar la búsqueda y devolver los resultados. +3. Almacenamos el valor introducido en la entrada de texto en una variable llamada `searchName`, antes de vaciar la entrada de texto y volver a enfocarla, listos para la siguiente búsqueda. + Tenga en cuenta que también ejecutamos el método [`toLowerCase()`](/es/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase) en la cadena, de modo que las búsquedas no distingan entre mayúsculas y minúsculas. +4. Ahora pasemos a la parte interesante, el bucle `for...of`: -5. If the contact name does not match the entered search, the paragraph text is set to "Contact not found.", and the loop continues iterating. + 1. Dentro del bucle, primero dividimos el contacto actual en el carácter de dos puntos y almacenamos los dos valores resultantes en un arreglo llamado `splitContact`. + 2. Luego usamos una instrucción condicional para probar si `splitContact [0]` (el nombre del contacto, nuevamente en minúsculas con [`toLowerCase()`](/es/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase)) es igual al `searchName` ingresado. + Si es así, introducimos una cadena en el párrafo para informar cuál es el número del contacto y usamos `break` para finalizar el bucle. -> **Nota:** Note: You can view the [full source code on GitHub](https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/contact-search.html) too (also [see it running live](http://mdn.github.io/learning-area/javascript/building-blocks/loops/contact-search.html)). +5. Después del bucle, verificamos si configuramos un contacto y, de lo contrario, configuramos el texto del párrafo como "Contacto no encontrado". -## Skipping iterations with continue +> **Nota:** También puedes ver el [código fuente completo en GitHub](https://github.com/mdn/learning-area/blob/main/javascript/building-blocks/loops/contact-search.html) (también [verlo en vivo](https://mdn.github.io/learning-area/javascript/building-blocks/loops/contact-search.html)). -The [continue](/es/docs/Web/JavaScript/Reference/Statements/continue) statement works in a similar manner to `break`, but instead of breaking out of the loop entirely, it skips to the next iteration of the loop. Let's look at another example that takes a number as an input, and returns only the numbers that are squares of integers (whole numbers). +## Omitir iteraciones con continue -The HTML is basically the same as the last example — a simple text input, and a paragraph for output. The JavaScript is mostly the same too, although the loop itself is a bit different: +La instrucción [continue](/es/docs/Web/JavaScript/Reference/Statements/continue) funciona de manera similar a `break`, pero en lugar de salir del bucle por completo, salta a la siguiente iteración del bucle. +Veamos otro ejemplo que toma un número como entrada y devuelve solo los números que son cuadrados de enteros (números enteros). -```js -var num = input.value; +El HTML es básicamente el mismo que el último ejemplo: una entrada numérica simple y un párrafo para la salida. -for (var i = 1; i <= num; i++) { - var sqRoot = Math.sqrt(i); - if (Math.floor(sqRoot) !== sqRoot) { - continue; - } +```html + + + - para.textContent += i + " "; -} +

Resultado:

``` -Here's the output: - -```html hidden - - - - - Integer squares generator - - - - - - - -

Output:

- - - - +btn.addEventListener("click", () => { + para.textContent = "Resultado: "; + const num = input.value; + input.value = ""; + input.focus(); + for (let i = 1; i <= num; i++) { + let sqRoot = Math.sqrt(i); + if (Math.floor(sqRoot) !== sqRoot) { + continue; + } + para.textContent += `${i} `; + } +}); ``` -{{ EmbedLiveSample('Hidden_code_4', '100%', 100, "", "", "hide-codepen-jsfiddle") }} +Este es el resultado: -1. In this case, the input should be a number (`num`). The `for` loop is given a counter starting at 1 (as we are not interested in 0 in this case), an exit condition that says the loop will stop when the counter becomes bigger than the input `num`, and an iterator that adds 1 to the counter each time. -2. Inside the loop, we find the square root of each number using [Math.sqrt(i)](/es/docs/Web/JavaScript/Reference/Global_Objects/Math/sqrt), then check whether the square root is an integer by testing whether it is the same as itself when it has been rounded down to the nearest integer (this is what [Math.floor()](/es/docs/Web/JavaScript/Reference/Global_Objects/Math/floor) does to the number it is passed). -3. If the square root and the rounded down square root do not equal one another (`!==`), it means that the square root is not an integer, so we are not interested in it. In such a case, we use the `continue` statement to skip on to the next loop iteration without recording the number anywhere. -4. If the square root IS an integer, we skip past the if block entirely so the `continue` statement is not executed; instead, we concatenate the current `i` value plus a space on to the end of the paragraph content. +{{ EmbedLiveSample('omitir_iteraciones_con_continue', '100%', 100) }} -> **Nota:** You can view the [full source code on GitHub](https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/integer-squares.html) too (also [see it running live](http://mdn.github.io/learning-area/javascript/building-blocks/loops/integer-squares.html)). +1. En este caso, la entrada debe ser un número (`num`). Al bucle `for` se le da un contador que comienza en 1 (ya que no estamos interesados en 0 en este caso), una condición de salida que dice que el bucle se detendrá cuando el contador se vuelva más grande que la entrada `num`, y un iterador que suma 1 al contador cada vez. +2. Dentro del bucle, encontramos la raíz cuadrada de cada número usando [Math.sqrt(i)](/es/docs/Web/JavaScript/Reference/Global_Objects/Math/sqrt), luego verificamos si la raíz cuadrada es un entero probando si es igual a sí misma cuando se ha redondeado al entero más cercano (esto es lo que [Math.floor()](/es/docs/Web/JavaScript/Reference/Global_Objects/Math/floor) hace al número que se pasa). +3. Si la raíz cuadrada y la raíz cuadrada redondeada hacia abajo no son iguales entre sí (`!==`), significa que la raíz cuadrada no es un número entero, por lo que no nos interesa. En tal caso, usamos la instrucción `continue` para saltar a la siguiente iteración de bucle sin registrar el número en ninguna parte. +4. Si la raíz cuadrada es un número entero, omitimos por completo el bloque `if`, por lo que no se ejecuta la instrucción `continue`; en su lugar, concatenamos el valor `i` actual más un espacio al final del contenido del párrafo. -## while and do ... while +> **Nota:** También puedes ver el [código fuente completo en GitHub](https://github.com/mdn/learning-area/blob/main/javascript/building-blocks/loops/integer-squares.html) (también [verlo en vivo](https://mdn.github.io/learning-area/javascript/building-blocks/loops/integer-squares.html)). -`for` is not the only type of loop available in JavaScript. There are actually many others and, while you don't need to understand all of these now, it is worth having a look at the structure of a couple of others so that you can recognize the same features at work in a slightly different way. +## while y do...while -First, let's have a look at the [while](/es/docs/Web/JavaScript/Reference/Statements/while) loop. This loop's syntax looks like so: +`for` no es el único tipo de bucle disponible en JavaScript. En realidad, hay muchos otros y, aunque no es necesario que entiendas todos estos ahora, vale la pena echar un vistazo a la estructura de un par de otros para que puedas reconocer las mismas características en el trabajo de una manera ligeramente diferente. -``` -initializer -while (exit-condition) { - // code to run +Primero, echemos un vistazo al bucle [while](/es/docs/Web/JavaScript/Reference/Statements/while). La sintaxis de este bucle se ve así: - final-expression +```js-nolint +inicializador +while(condición) { + // código a ejecutar + + expresión-final } ``` -This works in a very similar way to the for loop, except that the initializer variable is set before the loop, and the final-expression is included inside the loop after the code to run — rather than these two items being included inside the parentheses. The exit-condition is included inside the parentheses, which are preceded by the `while` keyword rather than `for`. +Esto funciona de una manera muy similar al bucle `for`, excepto que la variable inicializadora se establece antes del bucle, y la expresión final se incluye dentro del bucle después del código a ejecutar, en lugar de que estos dos elementos se incluyan dentro de los paréntesis. +La condición se incluye dentro de los paréntesis, que están precedidos por la palabra clave `while` en lugar de `for`. -The same three items are still present, and they are still defined in the same order as they are in the for loop — this makes sense, as you still have to have an initializer defined before you can check whether it has reached the exit-condition; the final-condition is then run after the code inside the loop has run (an iteration has been completed), which will only happen if the exit-condition has still not been reached. +Los mismos tres elementos todavía están presentes, y todavía están definidos en el mismo orden en que están en el bucle for. +Esto se debe a que debe tener un inicializador definido antes de poder verificar si la condición es verdadera o no. +La expresión final se ejecuta después de que se haya ejecutado el código dentro del bucle (se ha completado una iteración), lo que solo ocurrirá si la condición sigue siendo cierta. -Let's have a look again at our cats list example, but rewritten to use a while loop: +Echemos un vistazo de nuevo a nuestro ejemplo de lista de gatos, pero reescrito para usar un bucle while: ```js -var i = 0; +const cats = ["Pete", "Biggles", "Jasmine"]; + +let myFavoriteCats = "Mis gatos se llaman "; + +let i = 0; while (i < cats.length) { if (i === cats.length - 1) { - info += "and " + cats[i] + "."; + myFavoriteCats += `y ${cats[i]}.`; } else { - info += cats[i] + ", "; + myFavoriteCats += `${cats[i]}, `; } i++; } + +console.log(myFavoriteCats); // "Mis gatos se llaman Pete, Biggles y Jasmine." ``` -> **Nota:** This still works just the same as expected — have a look at it [running live on GitHub](http://mdn.github.io/learning-area/javascript/building-blocks/loops/while.html) (also view the [full source code](https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/while.html)). +> **Nota:** Esto sigue funcionando exactamente como se esperaba: échale un vistazo al [código fuente completo](https://mdn.github.io/learning-area/javascript/building-blocks/loops/while.html) (también puedes ver el [código fuente completo](https://github.com/mdn/learning-area/blob/main/javascript/building-blocks/loops/while.html)). -The [do...while](/es/docs/Web/JavaScript/Reference/Statements/do...while) loop is very similar, but provides a variation on the while structure: +El bucle [do...while](/es/docs/Web/JavaScript/Reference/Statements/do...while) es muy similar, pero proporciona una variación en la estructura while: -``` -initializer +```js-nolint +inicializador do { - // code to run + // código a ejecutar - final-expression -} while (exit-condition) + expresión-final +} while (condición) ``` -In this case, the initializer again comes first, before the loop starts. The `do` keyword directly precedes the curly braces containing the code to run and the final-expression. +En este caso, el inicializador vuelve a aparecer primero, antes de que comience el bucle. La palabra clave precede directamente a las llaves que contienen el código a ejecutar y la expresión final. -The differentiator here is that the exit-condition comes after everything else, wrapped in parentheses and preceded by a `while` keyword. In a `do...while` loop, the code inside the curly braces is always run once before the check is made to see if it should be executed again (in while and for, the check comes first, so the code might never be executed). +La principal diferencia entre un bucle `do...while` y un bucle `while` es que _el código dentro de un bucle `do...while` siempre se ejecuta al menos una vez_. Esto se debe a que la condición viene después del código dentro del bucle. Así que siempre ejecutamos ese código, luego verificamos si necesitamos ejecutarlo de nuevo. En los bucles `while` y `for`, la comprobación es lo primero, por lo que es posible que el código nunca se ejecute. -Let's rewrite our cat listing example again to use a `do...while` loop: +Volvamos a escribir nuestro ejemplo de listado de gatos para usar un bucle de "do...while": ```js -var i = 0; +const cats = ["Pete", "Biggles", "Jasmine"]; + +let myFavoriteCats = "Mis gatos se llaman "; + +let i = 0; do { if (i === cats.length - 1) { - info += "and " + cats[i] + "."; + myFavoriteCats += `y ${cats[i]}.`; } else { - info += cats[i] + ", "; + myFavoriteCats += `${cats[i]}, `; } i++; } while (i < cats.length); + +console.log(myFavoriteCats); // "Mis gatos se llaman Pete, Biggles y Jasmine." ``` -> **Nota:** Again, this works just the same as expected — have a look at it [running live on GitHub](http://mdn.github.io/learning-area/javascript/building-blocks/loops/do-while.html) (also view the [full source code](https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/do-while.html)). +> **Nota:** De nuevo, esto funciona igual que lo esperado: échale un vistazo al [código fuente completo](https://mdn.github.io/learning-area/javascript/building-blocks/loops/do-while.html) (también puedes ver el [código fuente completo](https://github.com/mdn/learning-area/blob/main/javascript/building-blocks/loops/do-while.html)). -> **Advertencia:** **Important**: With while and do...while — as with all loops — you must make sure that the initializer is iterated so that it eventually reaches the exit condition. If not, the loop will go on forever, and either the browser will force it to stop, or it will crash. This is called an **infinite loop**. +> **Advertencia:** Con while y do...while, como con todos los bucles, debe asegurarse de que el inicializador se incremente o, según el caso, se disminuya, para que la condición finalmente se vuelva falsa. +> Si no, el bucle continuará para siempre y el navegador lo obligará a detenerse o se bloqueará. Esto se llama un **bucle infinito**. -## Active learning: Launch countdown! +## Aprendizaje activo: iniciar cuenta regresiva -In this exercise, we want you to print out a simple launch countdown to the output box, from 10 down to Blast off. Specifically, we want you to: +En este ejercicio, queremos que imprima una cuenta regresiva de lanzamiento simple para la caja de salida, desde 10 hasta Blastoff. +En concreto, queremos: -- Loop from 10 down to 0. We've provided you with an initializer — `var i = 10;`. -- For each iteration, create a new paragraph and append it to the output `
`, which we've selected using `var output = document.querySelector('.output');`. In comments, we've provided you with three code lines that need to be used somewhere inside the loop: +- Bucle de 10 a 0. Te hemos proporcionado un inicializador: `let i = 10;`. +- Para cada iteración, cree un nuevo párrafo y añádalo a la salida `
`, que hemos seleccionado usando `const output = document.querySelector('.output');`. + En los comentarios, le proporcionamos tres líneas de código que deben usarse en algún lugar dentro del bucle: - - `var para = document.createElement('p');` — creates a new paragraph. - - `output.appendChild(para);` — appends the paragraph to the output `
`. - - `para.textContent =` — makes the text inside the paragraph equal to whatever you put on the right hand side, after the equals sign. + - `const para = document.createElement('p');`: crea un nuevo párrafo. + - `output.appendChild(para);`: añade el párrafo a la salida `
`. + - `para.textContent =`: hace que el texto dentro del párrafo sea igual a lo que pongas en el lado derecho, después del signo igual. -- Different iteration numbers require different text to be put in the paragraph for that iteration (you'll need a conditional statement and multiple `para.textContent =` lines): +- Los diferentes números de iteración requieren que se coloque un texto diferente en el párrafo para esa iteración (necesitarás una instrucción condicional y varias líneas de `para.textContent =`): - - If the number is 10, print "Countdown 10" to the paragraph. - - If the number is 0, print "Blast off!" to the paragraph. - - For any other number, print just the number to the paragraph. + - Si el número es 10, imprima "Cuenta regresiva 10" en el párrafo. + - Si el número es 0, imprima "Blast off!" en el párrafo. + - Para cualquier otro número, imprime solo el número en el párrafo. -- Remember to include an iterator! However, in this example we are counting down after each iteration, not up, so you **don't** want `i++` — how do you iterate downwards? +- ¡Recuerda incluir un iterador! Sin embargo, en este ejemplo estamos contando hacia atrás después de cada iteración, no hacia arriba, por lo que **no** quieres `i++`: ¿cómo iteras hacia abajo? -If you make a mistake, you can always reset the example with the "Reset" button. If you get really stuck, press "Show solution" to see a solution. +> **Nota:** Si comienza a escribir el bucle (por ejemplo, (while(i>=0)), es posible que el navegador se atasque porque aún no ha ingresado la condición final. Así que ten cuidado con esto. Puedes empezar a escribir tu código en un comentario para hacer frente a este problema y eliminar el comentario después de terminar. -###### Active learning +Si comete un error, siempre puede restablecer el ejemplo con el botón "Restablecer". +Si te quedas realmente atascado, pulsa "Mostrar solución" para ver una solución. -```html hidden -

Live output

+```html oculto +

Salida en vivo

-

Editable code

+

Código editable

- Press Esc to move focus away from the code area (Tab inserts a tab character). + Pulse Esc para alejar el foco del área de código (Tab inserta un carácter de + tabulación).

- - + +
``` -```css hidden +```css html { font-family: sans-serif; } @@ -516,11 +654,11 @@ body { ``` ```js hidden -var textarea = document.getElementById("code"); -var reset = document.getElementById("reset"); -var solution = document.getElementById("solution"); -var code = textarea.value; -var userEntry = textarea.value; +const textarea = document.getElementById("code"); +const reset = document.getElementById("reset"); +const solution = document.getElementById("solution"); +let code = textarea.value; +let userEntry = textarea.value; function updateCode() { eval(textarea.value); @@ -530,30 +668,48 @@ reset.addEventListener("click", function () { textarea.value = code; userEntry = textarea.value; solutionEntry = jsSolution; - solution.value = "Show solution"; + solution.value = "Mostrar solución"; updateCode(); }); solution.addEventListener("click", function () { - if (solution.value === "Show solution") { + if (solution.value === "Mostrar solución") { textarea.value = solutionEntry; - solution.value = "Hide solution"; + solution.value = "Ocultar solución"; } else { textarea.value = userEntry; - solution.value = "Show solution"; + solution.value = "Mostrar solución"; } updateCode(); }); -var jsSolution = - "var output = document.querySelector('.output');\noutput.innerHTML = '';\n\nvar i = 10;\n\nwhile(i >= 0) {\n var para = document.createElement('p');\n if(i === 10) {\n para.textContent = 'Countdown ' + i;\n } else if(i === 0) {\n para.textContent = 'Blast off!';\n } else {\n para.textContent = i;\n }\n\n output.appendChild(para);\n\n i--;\n}"; -var solutionEntry = jsSolution; +let jsSolution = `const output = document.querySelector('.output'); +output.innerHTML = ''; + +let i = 10; + +while (i >= 0) { + const para = document.createElement('p'); + if (i === 10) { + paragraphtextContent = \`Cuenta atrás \${i}\`; + } else if (i === 0) { + para.textContent = 'Blast off!'; + } else { + para.textContent = i; + } + + output.appendChild(para); + + i--; +}`; + +let solutionEntry = jsSolution; textarea.addEventListener("input", updateCode); window.addEventListener("load", updateCode); -// stop tab key tabbing out of textarea and -// make it write a tab at the caret position instead +// detener la tabulación de la tecla tabulación fuera del área de texto y +// hacer que escriba una tabulación en la posición del cursor en su lugar textarea.onkeydown = function (e) { if (e.keyCode === 9) { @@ -567,28 +723,28 @@ textarea.onkeydown = function (e) { }; function insertAtCaret(text) { - var scrollPos = textarea.scrollTop; - var caretPos = textarea.selectionStart; - - var front = textarea.value.substring(0, caretPos); - var back = textarea.value.substring( + const scrollPos = textarea.scrollTop; + let caretPos = textarea.selectionStart; + const front = textarea.value.substring(0, caretPos); + const back = textarea.value.substring( textarea.selectionEnd, textarea.value.length, ); + textarea.value = front + text + back; - caretPos = caretPos + text.length; + caretPos += text.length; textarea.selectionStart = caretPos; textarea.selectionEnd = caretPos; textarea.focus(); textarea.scrollTop = scrollPos; } -// Update the saved userCode every time the user updates the text area code +// Actualizar el userCode guardado cada vez que el usuario actualice el código de área de texto -textarea.onkeyup = function () { - // We only want to save the state when the user code is being shown, - // not the solution, so that solution is not saved over the user code - if (solution.value === "Show solution") { +textarea.onkeyup = () => { + // Solo queremos guardar el estado cuando se muestra el código de usuario, + // no la solución, para que la solución no se guarde sobre el código de usuario + if (solution.value === "Mostrar solución") { userEntry = textarea.value; } else { solutionEntry = textarea.value; @@ -598,50 +754,53 @@ textarea.onkeyup = function () { }; ``` -{{ EmbedLiveSample('Active_learning', '100%', 880, "", "", "hide-codepen-jsfiddle") }} +{{ EmbedLiveSample('aprendizaje_activo_iniciar_cuenta_regresiva', '100%', 900) }} -## Active learning: Filling in a guest list +## Aprendizaje activo: rellenar una lista de invitados -In this exercise, we want you to take a list of names stored in an array, and put them into a guest list. But it's not quite that easy — we don't want to let Phil and Lola in because they are greedy and rude, and always eat all the food! We have two lists, one for guests to admit, and one for guests to refuse. +En este ejercicio, queremos que tomes una lista de nombres almacenados en un arreglo y los pongas en una lista de invitados. Pero no es tan fácil: ¡no queremos dejar entrar a Phil y Lola porque son codiciosos y groseros, y siempre comen toda la comida! Tenemos dos listas, una para que los huéspedes la admitan y otra para que los huéspedes la rechacen. -Specifically, we want you to: +En concreto, queremos: -- Write a loop that will iterate from 0 to the length of the `people` array. You'll need to start with an initializer of `var i = 0;`, but what exit condition do you need? -- During each loop iteration, check if the current array item is equal to "Phil" or "Lola" using a conditional statement: +- Escribe un bucle que itere a través del arreglo `people`. +- Durante cada iteración de bucle, compruebe si el elemento del arreglo actual es igual a "Phil" o "Lola" utilizando una instrucción condicional: - - If it is, concatenate the array item to the end of the `refused` paragraph's `textContent`, followed by a comma and a space. - - If it isn't, concatenate the array item to the end of the `admitted` paragraph's `textContent`, followed by a comma and a space. + - Si es así, concatene el elemento del arreglo al final de `textContent` del párrafo `refused`, seguido de una coma y un espacio. + - Si no es así, concatene el elemento del arreglo hasta el final del `textContent` del párrafo `admitted`, seguido de una coma y un espacio. -We've already provided you with: +Ya te hemos proporcionado: -- `var i = 0;` — Your initializer. -- `refused.textContent +=` — the beginnings of a line that will concatenate something on to the end of `refused.textContent`. -- `admitted.textContent +=` — the beginnings of a line that will concatenate something on to the end of `admitted.textContent`. +- `refused.textContent +=`: los inicios de una línea que concatenará algo al final de `refused.textContent`. +- `admitted.textContent +=`; los inicios de una línea que concatenará algo al final de `admitted.textContent`. -Extra bonus question — after completing the above tasks successfully, you will be left with two lists of names, separated by commas, but they will be untidy — there will be a comma at the end of each one. Can you work out how to write lines that slice the last comma off in each case, and add a full stop to the end? Have a look at the [Useful string methods](/es/docs/Learn/JavaScript/First_steps/Useful_string_methods) article for help. +Pregunta de bonificación adicional: después de completar las tareas anteriores con éxito, te quedarán dos listas de nombres, separadas por comas, pero estarán desordenadas: habrá una coma al final de cada una. +¿Puedes averiguar cómo escribir líneas que corten la última coma en cada caso y añadir un punto al final? +Consulta el artículo [Métodos de cadenas útiles](/es/docs/Learn/JavaScript/First_steps/Useful_string_methods) para obtener ayuda. -If you make a mistake, you can always reset the example with the "Reset" button. If you get really stuck, press "Show solution" to see a solution. +Si comete un error, siempre puede restablecer el ejemplo con el botón "Restablecer". +Si te quedas realmente atascado, pulsa "Mostrar solución" para ver una solución. -```html hidden -

Live output

+```html oculto +

Salida en vivo

-

Admit:

-

Refuse:

+

Admitir:

+

Rechazar:

-

Editable code

+

Código editable

- Press Esc to move focus away from the code area (Tab inserts a tab character). + Pulse Esc para alejar el foco del área de código (Tab inserta un carácter de + tabulación).

- - + +
``` @@ -677,11 +836,11 @@ body { ``` ```js hidden -var textarea = document.getElementById("code"); -var reset = document.getElementById("reset"); -var solution = document.getElementById("solution"); -var code = textarea.value; -var userEntry = textarea.value; +const textarea = document.getElementById("code"); +const reset = document.getElementById("reset"); +const solution = document.getElementById("solution"); +let code = textarea.value; +let userEntry = textarea.value; function updateCode() { eval(textarea.value); @@ -691,30 +850,48 @@ reset.addEventListener("click", function () { textarea.value = code; userEntry = textarea.value; solutionEntry = jsSolution; - solution.value = "Show solution"; + solution.value = "Mostrar solución"; updateCode(); }); solution.addEventListener("click", function () { - if (solution.value === "Show solution") { + if (solution.value === "Mostrar solución") { textarea.value = solutionEntry; - solution.value = "Hide solution"; + solution.value = "Ocultar solución"; } else { textarea.value = userEntry; - solution.value = "Show solution"; + solution.value = "Mostrar solución"; } updateCode(); }); -var jsSolution = - "var people = ['Chris', 'Anne', 'Colin', 'Terri', 'Phil', 'Lola', 'Sam', 'Kay', 'Bruce'];\n\nvar admitted = document.querySelector('.admitted');\nvar refused = document.querySelector('.refused');\n\nadmitted.textContent = 'Admit: ';\nrefused.textContent = 'Refuse: '\nvar i = 0;\n\ndo {\n if(people[i] === 'Phil' || people[i] === 'Lola') {\n refused.textContent += people[i] + ', ';\n } else {\n admitted.textContent += people[i] + ', ';\n }\n i++;\n} while(i < people.length);\n\nrefused.textContent = refused.textContent.slice(0,refused.textContent.length-2) + '.';\nadmitted.textContent = admitted.textContent.slice(0,admitted.textContent.length-2) + '.';"; -var solutionEntry = jsSolution; +const jsSolution = ` +const people = ['Chris', 'Anne', 'Colin', 'Terri', 'Phil', 'Lola', 'Sam', 'Kay', 'Bruce']; + +const admitted = document.querySelector('.admitted'); +const refused = document.querySelector('.refused'); + +admitted.textContent = 'Admitir: '; +refused.textContent = 'Rechazar: '; + +for (const person of people) { + if (person === 'Phil' || person === 'Lola') { + refused.textContent += \`\${person}, \`; + } else { + admitted.textContent += \`\${person}, \`; + } +} + +refused.textContent = refused.textContent.slice(0,refused.textContent.length-2) + '.'; +admitted.textContent = admitted.textContent.slice(0,admitted.textContent.length-2) + '.';`; + +let solutionEntry = jsSolution; textarea.addEventListener("input", updateCode); window.addEventListener("load", updateCode); -// stop tab key tabbing out of textarea and -// make it write a tab at the caret position instead +// detener la tabulación de la tecla tabulación fuera del área de texto y +// hacer que escriba una tabulación en la posición del cursor en su lugar textarea.onkeydown = function (e) { if (e.keyCode === 9) { @@ -728,28 +905,28 @@ textarea.onkeydown = function (e) { }; function insertAtCaret(text) { - var scrollPos = textarea.scrollTop; - var caretPos = textarea.selectionStart; - - var front = textarea.value.substring(0, caretPos); - var back = textarea.value.substring( + const scrollPos = textarea.scrollTop; + let caretPos = textarea.selectionStart; + const front = textarea.value.substring(0, caretPos); + const back = textarea.value.substring( textarea.selectionEnd, textarea.value.length, ); + textarea.value = front + text + back; - caretPos = caretPos + text.length; + caretPos += text.length; textarea.selectionStart = caretPos; textarea.selectionEnd = caretPos; textarea.focus(); textarea.scrollTop = scrollPos; } -// Update the saved userCode every time the user updates the text area code +// Actualizar el userCode guardado cada vez que el usuario actualice el código de área de texto -textarea.onkeyup = function () { - // We only want to save the state when the user code is being shown, - // not the solution, so that solution is not saved over the user code - if (solution.value === "Show solution") { +textarea.onkeyup = () => { + // Solo queremos guardar el estado cuando se muestra el código de usuario, + // no la solución, para que la solución no se guarde sobre el código de usuario + if (solution.value === "Mostrar solución") { userEntry = textarea.value; } else { solutionEntry = textarea.value; @@ -759,58 +936,75 @@ textarea.onkeyup = function () { }; ``` -{{ EmbedLiveSample('Active_learning_2', '100%', 680, "", "", "hide-codepen-jsfiddle") }} +{{ EmbedLiveSample('aprendizaje_activo_rellenar_una_lista_de_invitados', '100%', 680) }} + +## ¿Qué tipo de bucle debes usar? + +Si está iterando a través de un arreglo o algún otro objeto que lo admita, y no necesita acceder a la posición de índice de cada elemento, entonces `for...of` es la mejor opción. Es más fácil de leer y hay menos para equivocarse. -## Which loop type should you use? +Para otros usos, los bucles `for`, `while` y `do...while` son en gran medida intercambiables. +Todos se pueden usar para resolver los mismos problemas, y cuál uses dependerá en gran medida de tus preferencias personales: cuál te resulta más fácil de recordar o más intuitivo. +Recomendaríamos `for`, al menos para empezar, ya que es probablemente el más fácil para recordar todo: el inicializador, la condición y la expresión final tienen que ir perfectamente entre paréntesis, por lo que es fácil ver dónde están y comprobar que no te los estás perdiendo. -For basic uses, `for`, `while`, and `do...while` loops are largely interchangeable. They can all be used to solve the same problems, and which one you use will largely depend on your personal preference — which one you find easiest to remember or most intuitive. Let's have a look at them again. +Echémosles un vistazo a todos de nuevo. -First `for`: +Primero `for...of`: +```js-nolint +for (const elemento of arreglo) { + // código a ejecutar +} ``` -for (initializer; exit-condition; final-expression) { - // code to run + +`for`: + +```js-nolint +for (inicializador; condición; expresión-final) { + // código a ejecutar } ``` `while`: -``` -initializer -while (exit-condition) { - // code to run +```js-nolint +inicializador +while(condición) { + // código a ejecutar - final-expression + expresión-final } ``` -and finally `do...while`: +y finalmente `do...while`: -``` -initializer +```js-nolint +inicializador do { - // code to run + // código a ejecutar - final-expression -} while (exit-condition) + expresión-final +} while (condición) ``` -We would recommend `for`, at least to begin with, as it is probably the easiest for remembering everything — the initializer, exit-condition, and final-expression all have to go neatly into the parentheses, so it is easy to see where they are and check that you aren't missing them. +> **Nota:** También hay otros tipos/características de bucle, que son útiles en situaciones avanzadas/especializadas y más allá del alcance de este artículo. Si quieres ir más allá con tu aprendizaje en bucle, lee nuestra [Guía de bucles e iteraciones](/es/docs/Web/JavaScript/Guide/Loops_and_iteration) avanzada. + +## Pon a prueba tus habilidades -> **Nota:** There are other loop types/features too, which are useful in advanced/specialized situations and beyond the scope of this article. If you want to go further with your loop learning, read our advanced [Loops and iteration guide](/es/docs/Web/JavaScript/Guide/Loops_and_iteration). +Has llegado al final de este artículo, pero ¿puedes recordar la información más importante? Puedes encontrar algunas pruebas adicionales para verificar que has conservado esta información antes de continuar. Consulta [Pon a prueba tus habilidades: bucles](/es/docs/Learn/JavaScript/Building_blocks/Test_your_skills:_Loops). -## Conclusion +## Conclusión -This article has revealed to you the basic concepts behind, and different options available when, looping code in JavaScript. You should now be clear on why loops are a good mechanism for dealing with repetitive code, and be raring to use them in your own examples! +Este artículo te ha revelado los conceptos básicos que hay detrás y las diferentes opciones disponibles al hacer bucles de código en JavaScript. +¡Ahora deberías tener claro por qué los bucles son un buen mecanismo para lidiar con el código repetitivo y tener ganas de usarlos en tus propios ejemplos! -If there is anything you didn't understand, feel free to read through the article again, or [contact us](/es/Learn#Contact_us) to ask for help. +Si hay algo que no entendiste, vuelve a leer el artículo o [ponte en contacto con nosotros](/es/docs/Learn#contact_us) para pedir ayuda. -## See also +## Vease también -- [Loops and iteration in detail](/es/docs/Web/JavaScript/Guide/Loops_and_iteration) -- [for statement reference](/es/docs/Web/JavaScript/Reference/Statements/for) -- [while](/es/docs/Web/JavaScript/Reference/Statements/while) and [do...while](/es/docs/Web/JavaScript/Reference/Statements/do...while) references -- [break](/es/docs/Web/JavaScript/Reference/Statements/break) and [continue](/es/docs/Web/JavaScript/Reference/Statements/continue) references -- [What's the Best Way to Write a JavaScript For Loop?](https://www.impressivewebs.com/javascript-for-loop/) — some advanced loop best practices +- [Bucles e iteración en detalle](/es/docs/Web/JavaScript/Guide/Loops_and_iteration) +- [for...of referencia](/es/docs/Web/JavaScript/Reference/Statements/for...of) +- [Referencia de la declaración for](/es/docs/Web/JavaScript/Reference/Statements/for) +- Referencias de [while](/es/docs/Web/JavaScript/Reference/Statements/while) y [do...while](/es/docs/Web/JavaScript/Reference/Statements/do...while) +- Referencias de [break](/es/docs/Web/JavaScript/Reference/Statements/break) y [continue](/es/docs/Web/JavaScript/Reference/Statements/continue) {{PreviousMenuNext("Learn/JavaScript/Building_blocks/conditionals","Learn/JavaScript/Building_blocks/Functions", "Learn/JavaScript/Building_blocks")}} diff --git a/files/es/mdn/at_ten/index.md b/files/es/mdn/at_ten/index.md index 899ff8d447aa5a..006af4a4c68d3e 100644 --- a/files/es/mdn/at_ten/index.md +++ b/files/es/mdn/at_ten/index.md @@ -17,8 +17,6 @@ Por diez años, la comunidad MDN ha estado documentando la Web abierta. Desde la [Aprende más sobre contribuyendo](/es/docs/MDN_at_ten/Contributing_to_MDN) -{{TenthCampaignQuote}} - ## Subnav 1. [MDN en 10](/es/docs/MDN_at_ten/) diff --git a/files/es/mdn/writing_guidelines/page_structures/page_types/aria_page_template/index.md b/files/es/mdn/writing_guidelines/page_structures/page_types/aria_page_template/index.md new file mode 100644 index 00000000000000..f3b06671b9051a --- /dev/null +++ b/files/es/mdn/writing_guidelines/page_structures/page_types/aria_page_template/index.md @@ -0,0 +1,141 @@ +--- +title: "ARIA: Plantilla de página" +slug: MDN/Writing_guidelines/Page_structures/Page_types/ARIA_Page_Template +l10n: + sourceCommit: dad6b0e057cd37b4408cdede8b9f568c56df9a82 +--- + +{{MDNSidebar}} + +## Metadatos de la página + +### Title y slug + +Una página de rol de ARIA debe tener un `title` y un `slug` de `ARIA: Nombre del rol`. Por ejemplo, el [rol de botón](/es/docs/Web/Accessibility/ARIA/Roles/button_role) tiene un `title` y `slug` de `ARIA/NameOfTheRole_role` y el atributo [aria-labelledby](/es/docs/Web/Accessibility/ARIA/Attributes/aria-labelledby) tiene un `title` de `aria-labelledby`. + +### Principales macros + +Aparecen varias llamadas a macros en la parte superior de la sección de contenido. Debes actualizarlos o eliminarlos de acuerdo con los siguientes consejos: + +- \\{{deprecated_header}}: genera un banner de **Obsoleto** que indica que la tecnología está [obsoleta](/es/docs/MDN/Writing_guidelines/Experimental_deprecated_obsolete#deprecated). Si no es así, puede eliminar la llamada de macro. +- \\{{ariaref}}: genera un menú lateral ARIA adecuado, dependiendo de las etiquetas que se incluyan en la página. + +### Etiquetas + +En las subpáginas de roles o atributos de ARIA, debes incluir las siguientes etiquetas (consulta la sección _Etiquetas_ en la parte inferior de la interfaz de usuario del editor): **ARIA**, **Reference**, **ARIA Role** o **ARIA Attribute**, _el nombre del Rol oo Atributo_ (por ejemplo **ARIA button** or **aria-labelledby**), **ARIA widget,** **Experimental** (si el atributo del rol es [experimental](/es/docs/MDN/Writing_guidelines/Experimental_deprecated_obsolete#experimental)), y **Obsoleto** (si es [obsoleto](/es/docs/MDN/Writing_guidelines/Experimental_deprecated_obsolete#deprecated)). + +### Especificaciones + +En el valor de la clave de metadatos `spec_urls`, actualice las URL para que apunten a los ID de url para las secciones correctas de las siguientes especificaciones: + +- [ARIA](https://w3c.github.io/aria/) +- [Prácticas de autoría de ARIA](https://w3c.github.io/aria-practices/) + +Recursos adicionales: + +- [Modelo de objetos de accesibilidad](https://wicg.github.io/aom/spec/) +- [ARIA en HTML](https://w3c.github.io/html-aria/) + +## Plantilla de página + +El párrafo de resumen comienza nombrando el rol o atributo y diciendo lo que hace. Idealmente, esto debería consistir en 1 o 2 oraciones cortas. Este contenido aparece como una sugerencia de herramienta en los enlaces a esta página, así que elabóralo bien. + +```html + +``` + +(Opcional) Incluya una breve descripción del ejemplo anterior. + +## Descripción + +Incluya una descripción completa del atributo o rol. + +### Roles, estados y propiedades de ARIA asociados + +- Nombre de los roles asociados + - : Explicación de requerimientos, enlace a páginas de características. +- Nombre de los atributos asociados + - : Explicación del requisito, enlace a las páginas del atributo, junto con el enlace a JS requerido para cambiar el valor, si corresponde. + +### Interacciones con el teclado + +### Funciones de JavaScript requeridas + +- Manejadores de eventos requeridos + - : Explicación de cada uno +- Cambio de valores de atributos + - : Explicación de cada uno + +> **Nota:** Incluye una nota sobre alternativas semánticas al uso de este rol o atributo. La primera regla de uso de ARIA es que puedes usar una función nativa con la semántica y el comportamiento que requieres ya incorporados, en lugar de reutilizar un elemento y **agregar** un rol, estado o propiedad de ARIA para hacerlo accesible, y luego hacerlo. Luego publique todos los detalles en la sección de mejores prácticas a continuación. + +## Ejemplos + +Tenga en cuenta que usamos el plural "Ejemplos" incluso si la página solo contiene un ejemplo. + +### Un encabezado descriptivo + +Cada ejemplo debe tener un encabezado H3 (`###`) que nombre el ejemplo. El encabezado debe ser descriptivo de lo que está haciendo el ejemplo. Por ejemplo, "Un ejemplo simple" no dice nada sobre el ejemplo y, por lo tanto, no es un buen encabezado. El encabezado debe ser conciso. Para una descripción más larga, use el párrafo después del encabezado. + +Consulta nuestra guía sobre cómo añadir [ejemplos de código](/es/docs/MDN/Writing_guidelines/Page_structures/Code_examples) para obtener más información. + +> **Nota:** A veces querrás enlazar a ejemplos dados en otra página. +> +> **Escenario 1:** Si tiene algunos ejemplos en esta página y algunos ejemplos más en otra página: +> +> Incluya un encabezado H3 (`###`) para cada ejemplo en esta página y luego un encabezado H3 final (`###`) con el texto "Más ejemplos", bajo el cual puede vincular los ejemplos en otras páginas. Por ejemplo: +> +> ```md +> ## Ejemplos +> +> ### Uso de la API fetch +> +> Ejemplo de Fetch +> +> ### Más ejemplos +> +> Enlaces a más ejemplos en otras páginas +> ``` +> +> **Escenario 2:** Si _solo_ tienes ejemplos en otra página y ninguno en esta página: +> +> No añada ningún encabezado H3; solo añada los enlaces directamente debajo del encabezado H2 "Ejemplos". Por ejemplo: +> +> ```md +> ## Ejemplos +> +> Para ver ejemplos de esta API, consulte [la página en fetch()](https://example.org). +> ``` + +## Problemas de accesibilidad + +Opcionalmente, advierte sobre cualquier posible problema de accesibilidad que exista con el uso de esta propiedad y cómo solucionarlos. Elimine esta sección si no hay ninguna para enumerar. + +## Mejores prácticas + +Opcionalmente, enumere las mejores prácticas que existen para este rol. Elimine la sección si no existe. + +### Beneficios añadidos + +- Rol asociado + - : Si ese rol es un padre, hijo o hermano requerido, y lo que hace. + +Cualquier beneficio adicional que esta función tenga para los usuarios no típicos de lectores de pantalla, como el reconocimiento de voz de Google o móvil. + +## Especificaciones + +`\{{Specifications}}` + +_Recuerde eliminar las comillas invertidas y la barra invertida para usar esta macro._ + +## Orden de precedencia + +¿Cuáles son las propiedades relacionadas y en qué orden se leerá este atributo o propiedad (qué propiedad tendrá prioridad sobre esta y qué propiedad se sobrescribirá)? + +## Compatibilidad con lectores de pantalla + +## Vease también + +Incluya enlaces a páginas de referencia y guías relacionadas con el rol o atributo actual. Para obtener más pautas, consulta la [sección Véase también](/es/docs/MDN/Writing_guidelines/Writing_style_guide#see_also_section) en la _Guía de estilo_. + +- link1 +- link2 diff --git a/files/es/web/http/cookies/index.md b/files/es/web/http/cookies/index.md index 725db3a168c550..81513b3606a4e9 100644 --- a/files/es/web/http/cookies/index.md +++ b/files/es/web/http/cookies/index.md @@ -181,41 +181,51 @@ Se presentan aquí algunas técnicas que se deberían usar para evitar que estas - Las cookies empleadas en acciones delicadas deberían de tener una vida útil breve. - Para más prevención visita [OWASP CSRF prevention cheat sheet](). -## Tracking and privacy +## Rastreo y privacidad -### Third-party cookies +### Cookies de terceros -Cookies have a domain associated to them. If this domain is the same as the domain of the page you are on, the cookies is said to be a _first-party cookie_. If the domain is different, it is said to be a _third-party cookie_. While first-party cookies are sent only to the server setting them, a web page may contain images or other components stored on servers in other domains (like ad banners). Cookies that are sent through these third-party components are called third-party cookies and are mainly used for advertising and tracking across the web. See for example the [types of cookies used by Google](https://www.google.com/policies/technologies/types/). Most browsers allow third-party cookies by default, but there are add-ons available to block them (for example, [Privacy Badger](https://addons.mozilla.org/en-US/firefox/addon/privacy-badger-firefox/) by the [EFF](https://www.eff.org/)). +Las Cookies tienen un dominio asociado a ellas. Si este dominio es el mismo que el dominio de la página en la que el cliente se encuentra, se llama _cookie de origen_. Si el dominio es distinto, se denomina _cookie de terceros_. Si bien las cookies de origen se envían únicamente al servidor que las configura, una página web puede contener imágenes u otros componentes almacenados en servidores de otros dominios (como publicidad). Las cookies que se envían a través de estos componentes de terceros se utilizan principalmente para publicidad y seguimiento en la web. Por ejemplo, [los tipos de cookies utilizadas por Google](https://www.google.com/policies/technologies/types/). -If you are not disclosing third-party cookies, consumer trust might get harmed if cookie use is discovered. A clear disclosure (such as in a privacy policy) tends to eliminate any negative effects of a cookie discovery. Some countries also have legislation about cookies. See for example Wikipedia's [cookie statement](https://wikimediafoundation.org/wiki/Cookie_statement). +Un servidor de terceros puede crear un perfil del historial y los hábitos de navegación de un usuario basándose en las cookies que le envía el mismo navegador al acceder a varios sitios. Firefox, de forma predeterminada, bloquea las cookies de terceros que se sabe que contienen rastreadores. Las cookies de terceros (o simplemente las cookies de seguimiento) también pueden bloquearse mediante otras configuraciones o extensiones del navegador. El bloqueo de cookies puede provocar que algunos componentes de terceros (como los widgets de redes sociales) no funcionen según lo previsto. -### Do-Not-Track +Hay algunas funciones útiles disponibles para los desarrolladores que desean respetar la privacidad del usuario y minimizar el seguimiento de terceros: -There are no legal or technological requirements for its use, but the {{HTTPHeader("DNT")}} header can be used to signal that a web application should disable either its tracking or cross-site user tracking of an individual user. See the {{HTTPHeader("DNT")}} header for more information. +- Los servidores pueden (y deberían) configurar el atributo SameSite para especificar si se pueden enviar o no cookies de terceros. +- Las cookies que tienen un estado de partición independiente (CHIPS) les permiten a los desarrolladores habilitar sus cookies en el almacenamiento particionado, con un contenedor de cookies separado por sitio de nivel superior. Esto permite que los usos válidos sin seguimiento de cookies de terceros sigan funcionando en navegadores que no permiten el uso de cookies para el seguimiento de terceros. -### EU cookie directive +## Regulaciones relacionadas a las cookies -Requirements for cookies across the EU are defined in [Directive 2009/136/EC](http://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:32009L0136) of the European Parliament and came into effect on 25 May 2011. A directive is not a law by itself, but a requirement for EU member states to put laws in place that meet the requirements of the directive. The actual laws can differ from country to country. +La legislación o normativa que cubre el uso de cookies incluye: -In short the EU directive means that before somebody can store or retrieve any information from a computer, mobile phone or other device, the user must give informed consent to do so. Many websites have added banners since then to inform the user about the use of cookies. +- El Reglamento General de Privacidad de Datos (RGPD) en la Unión Europea +- La Directiva sobre la privacidad electrónica en la Unión Europea +- Ley de Privacidad del Consumidor de California (CCPA) -For more, see [this Wikipedia section](https://en.wikipedia.org/wiki/HTTP_cookie#EU_cookie_directive) and consult state laws for the latest and most accurate information. +Estas regulaciones tienen alcance global. Se aplican a cualquier sitio del internet al que accedan usuarios de estas jurisdicciones (la UE y California, con la salvedad de que la ley de California se aplica sólo a entidades con ingresos brutos superiores a 25 millones de dólares, entre otras cosas). -### Zombie cookies and Evercookies +Estas regulaciones incluyen requisitos tales como: -A more radical approach to cookies are zombie cookies or "Evercookies" which are recreated after their deletion and are intentionally hard to delete forever. They are using the [Web storage API](/es/docs/Web/API/Web_Storage_API), Flash Local Shared Objects and other techniques to recreate themselves whenever the cookie's absence is detected. +- Notificar a los usuarios que el sitio utiliza cookies. +- Permitir a los usuarios escoger no recibir algunas o todas las cookies. +- Permitir a los usuarios utilizar la mayor parte del servicio sin recibir cookies. -- [Evercookie by Samy Kamkar](https://github.com/samyk/evercookie) -- [Zombie cookies on Wikipedia](https://en.wikipedia.org/wiki/Zombie_cookie) +Puede haber otras regulaciones que rijan el uso de cookies en tu ubicación. La carga de conocer y cumplir estas regulaciones recae sobre usted. Hay empresas que ofrecen un código de "banner de cookies" que le ayuda a cumplir con estas normativas. -## See also +## Otras formas de almacenar información en el navegador + +Otro enfoque para almacenar datos en el navegador es la [API de almacenamiento web](/es/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API). Las propiedades [window.sessionStorage](/es/docs/Web/API/Window/sessionStorage) y [window.localStorage](/es/docs/Web/API/Window/localStorage) corresponden a cookies de sesión y permanentes en duración, pero tienen límites de almacenamiento mayores que las cookies y nunca se envían a un servidor. Se pueden almacenar cantidades de datos más estructuradas y mayores utilizando la [API IndexedDB](/es/docs/Web/API/IndexedDB_API) o una biblioteca construida sobre ella. + +Existen algunas técnicas diseñadas para recrear las cookies después de eliminarlas. Se conocen como cookies "zombies". Estas técnicas violan los principios de privacidad y control del usuario, pueden violar las regulaciones de privacidad de datos y podrían exponer a un sitio web que las utilice a responsabilidad legal. + +## Véase También - {{HTTPHeader("Set-Cookie")}} - {{HTTPHeader("Cookie")}} - {{domxref("Document.cookie")}} - {{domxref("Navigator.cookieEnabled")}} -- [Inspecting cookies using the Storage Inspector](/es/docs/Tools/Storage_Inspector) +- [Inspeccionar cookies usando el Storage Inspector](/es/docs/Tools/Storage_Inspector) - [Cookie specification: RFC 6265](https://tools.ietf.org/html/rfc6265) - [Nicholas Zakas article on cookies](https://www.nczonline.net/blog/2009/05/05/http-cookies-explained/) - [Nicholas Zakas article on cookies and security](https://www.nczonline.net/blog/2009/05/12/cookies-and-security/) -- [HTTP cookie on Wikipedia](https://en.wikipedia.org/wiki/HTTP_cookie) +- [HTTP cookies en Wikipedia]() diff --git a/files/fr/glossary/accessible_name/index.md b/files/fr/glossary/accessible_name/index.md new file mode 100644 index 00000000000000..6b344c14afc0a0 --- /dev/null +++ b/files/fr/glossary/accessible_name/index.md @@ -0,0 +1,33 @@ +--- +title: Nom accessible +slug: Glossary/Accessible_name +l10n: + sourceCommit: 1f7c54fce7dc72e99e3d22ece8958db1290a7062 +--- + +{{GlossarySidebar}} + +Un **nom accessible** (accessible name en anglais) est le nom d'un élément d'interface utilisateur ; il s'agit du texte associé à un élément HTML qui fournit aux utilisateur·ice·s d'une technologie d'assistance une étiquette pour l'élément en question. + +Les noms accessibles indiquent l'objectif ou l'intention de l'élément. Cela aide les utilisateur·ice·s à comprendre à quoi sert l'élément et comment ils peuvent interagir avec lui. En général, les noms accessibles des éléments doivent être propres à une page. Cela permet aux utilisateur·ice·s de distinguer un élément des autres et d'identifier l'élément avec lequel ils veulent interagir. + +En fonction de l'élément et du balisage HTML, la valeur du nom accessible peut être dérivée du contenu visible (par exemple, le texte dans [`
`](/fr/docs/Web/HTML/Element/figcaption)) ou invisible (par exemple, l'attribut `aria-label` défini sur un élément), ou d'une combinaison des deux. La manière dont le nom accessible d'un élément est déterminé est basée sur [le calcul du nom accessible (en anglais)](https://www.w3.org/WAI/ARIA/apg/practices/names-and-descriptions/#name_calculation), qui est différent pour chaque élément. + +Il est préférable d'utiliser du texte visible comme noms accessibles. De nombreux éléments, notamment [``](/fr/docs/Web/HTML/Element/a), [``](/fr/docs/Web/HTML/Element/td) et [`