mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-02-18 19:00:36 -05:00
feat(curriculum): add iframe video workshop (#62053)
Co-authored-by: Sem Bauke <sem@freecodecamp.org> Co-authored-by: Ilenia <26656284+ilenia-magoni@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Jessica Wilkins <67210629+jdwilkin4@users.noreply.github.com>
This commit is contained in:
@@ -2151,6 +2151,12 @@
|
||||
"In these lectures, you will learn how to work with the <code>iframe</code> element which is used to embed an external site on your web page."
|
||||
]
|
||||
},
|
||||
"workshop-build-a-video-display-using-iframe": {
|
||||
"title": "Build a Video Display Using iframe",
|
||||
"intro": [
|
||||
"In this workshop, you'll learn how to work with the <code>iframe</code> element by building a video display."
|
||||
]
|
||||
},
|
||||
"lab-video-compilation-page": {
|
||||
"title": "Build a Video Compilation Page",
|
||||
"intro": [
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Introduction to the Build a Video Display Using iframe
|
||||
block: workshop-build-a-video-display-using-iframe
|
||||
superBlock: full-stack-developer
|
||||
---
|
||||
|
||||
## Introduction to the Build a Video Display Using iframe
|
||||
|
||||
This workshop focuses on how to build a video display feature with the `iframe` element.
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
id: 68b94f23f7b3ee14078c89c5
|
||||
title: Step 1
|
||||
challengeType: 0
|
||||
dashedName: step-1
|
||||
demoType: onLoad
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this workshop, you will use the `iframe` element to display a video. The basic HTML boilerplate has been prepared for you.
|
||||
|
||||
Begin by creating an `h1` element with the text `iframe Video Display`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have an `h1` element.
|
||||
|
||||
```js
|
||||
assert.exists(document.querySelector('h1'))
|
||||
```
|
||||
|
||||
Your `h1` element should have the text `iframe Video Display`.
|
||||
|
||||
```js
|
||||
assert.equal(document.querySelector('h1')?.textContent, 'iframe Video Display')
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Display Videos in an iframe</title>
|
||||
</head>
|
||||
<body>
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
id: 68ba9c4f1688914d72876093
|
||||
title: Step 2
|
||||
challengeType: 0
|
||||
dashedName: step-2
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now, create an `iframe` element. Don't put anything in it yet.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have an `iframe` element.
|
||||
|
||||
```js
|
||||
assert.exists(document.querySelector('iframe'))
|
||||
```
|
||||
|
||||
Your `iframe` element should be empty.
|
||||
|
||||
```js
|
||||
assert.equal(document.querySelector('iframe')?.innerHTML.trim(), '')
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Display Videos in an iframe</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>iframe Video Display</h1>
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
id: 68ba9c4f1688914d72876094
|
||||
title: Step 3
|
||||
challengeType: 0
|
||||
dashedName: step-3
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In the first lesson on the `iframe` element, you learned it's a replaced element just like `img`. That means it can also take the `width` and `height` properties to determine how tall and wide it should be.
|
||||
|
||||
Give your `iframe` element a `width` of `560` and a `height` of `315`.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `iframe` element should have a `width` attribute set to `560`.
|
||||
|
||||
```js
|
||||
const iframeEl = document.querySelector('iframe')
|
||||
assert.equal(iframeEl?.getAttribute('width'), '560')
|
||||
```
|
||||
|
||||
Your `iframe` element should have a `height` attribute set to `315`.
|
||||
|
||||
```js
|
||||
const iframeEl = document.querySelector('iframe')
|
||||
assert.equal(iframeEl?.getAttribute('height'), '315')
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Display Videos in an iframe</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>iframe Video Display</h1>
|
||||
--fcc-editable-region--
|
||||
<iframe>
|
||||
|
||||
</iframe>
|
||||
--fcc-editable-region--
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
id: 68ba9c4f1688914d72876095
|
||||
title: Step 4
|
||||
challengeType: 0
|
||||
dashedName: step-4
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The `iframe` element also takes an `src` attribute with a value that indicates the URL or the path of the resource to display.
|
||||
|
||||
Add an `src` attribute of `https://www.youtube.com/embed/I0_951_MPE0` to your `iframe` element.
|
||||
|
||||
At this point, you should see the video displaying on the page, but there are some more attributes you need to add.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `iframe` element should have an `src` attribute set to `https://www.youtube.com/embed/I0_951_MPE0`.
|
||||
|
||||
```js
|
||||
const iframeEl = document.querySelector('iframe')
|
||||
assert.equal(iframeEl?.getAttribute('src'), 'https://www.youtube.com/embed/I0_951_MPE0')
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Display Videos in an iframe</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>iframe Video Display</h1>
|
||||
--fcc-editable-region--
|
||||
<iframe
|
||||
width="560"
|
||||
height="315"
|
||||
|
||||
>
|
||||
|
||||
</iframe>
|
||||
--fcc-editable-region--
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@@ -0,0 +1,79 @@
|
||||
---
|
||||
id: 68ba9c4f1688914d72876096
|
||||
title: Step 5
|
||||
challengeType: 0
|
||||
dashedName: step-5
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
One of the attributes is `allow`. It's like a permission list that tells the browser what features the `iframe` is allowed to use.
|
||||
|
||||
Here's an `iframe` element with the `allow` attribute:
|
||||
|
||||
```html
|
||||
<iframe
|
||||
allow="accelerometer autoplay clipboard-write encrypted-media gyroscope picture-in-picture web-share"
|
||||
></iframe>
|
||||
```
|
||||
|
||||
Add the `allow` attribute with the value `accelerometer`, `autoplay`, and `clipboard-write`.
|
||||
|
||||
`accelerometer` lets the `iframe` use motion sensors so it can detect things like device tilting and rotation. `autoplay` lets the video start playing automatically, and `clipboard-write` lets the iframe write data to the user’s clipboard.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `iframe` element should have an `allow` attribute set to `accelerometer`.
|
||||
|
||||
```js
|
||||
const iframeEl = document.querySelector('iframe')
|
||||
const iframeElAllowAttr = iframeEl?.getAttribute('allow')
|
||||
const accelerometer = iframeElAllowAttr.trim().split(' ')[0]
|
||||
assert.strictEqual(accelerometer, 'accelerometer')
|
||||
```
|
||||
|
||||
The `allow` attribute of your `iframe` element should have `autoplay` as one of its values.
|
||||
|
||||
```js
|
||||
const iframeEl = document.querySelector('iframe')
|
||||
const iframeElAllowAttr = iframeEl?.getAttribute('allow')
|
||||
const autoplay = iframeElAllowAttr.trim().split(' ')[1]
|
||||
assert.strictEqual(autoplay, 'autoplay')
|
||||
```
|
||||
|
||||
The `allow` attribute of your `iframe` element should have `clipboard-write` as one of its values.
|
||||
|
||||
```js
|
||||
const iframeEl = document.querySelector('iframe')
|
||||
const iframeElAllowAttr = iframeEl?.getAttribute('allow')
|
||||
const clipboardWrite = iframeElAllowAttr.trim().split(' ')[2]
|
||||
assert.strictEqual(clipboardWrite, 'clipboard-write')
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Display Videos in an iframe</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>iframe Video Display</h1>
|
||||
--fcc-editable-region--
|
||||
<iframe
|
||||
width="560"
|
||||
height="315"
|
||||
src="https://www.youtube.com/embed/I0_951_MPE0"
|
||||
|
||||
>
|
||||
|
||||
</iframe>
|
||||
--fcc-editable-region--
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@@ -0,0 +1,69 @@
|
||||
---
|
||||
id: 68ba9c4f1688914d72876097
|
||||
title: Step 6
|
||||
challengeType: 0
|
||||
dashedName: step-6
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Add `encrypted-media`, `gyroscope`, and `web-share` to the existing values in the `allow` attribute.
|
||||
|
||||
These three will allow the use of encrypted media extensions to protect the video, let the iframe pop out into picture-in-picture mode when needed, and allow sharing the iframe content through the device's native share dialogs.
|
||||
|
||||
# --hints--
|
||||
|
||||
The `allow` attribute of your `iframe` element should have `encrypted-media` as one of its values.
|
||||
|
||||
```js
|
||||
const iframeEl = document.querySelector('iframe')
|
||||
const iframeElAllowAttr = iframeEl?.getAttribute('allow')
|
||||
const encryptedMedia = iframeElAllowAttr.trim().split(' ')[3]
|
||||
assert.strictEqual(encryptedMedia, 'encrypted-media')
|
||||
```
|
||||
|
||||
The `allow` attribute of your `iframe` element should have `gyroscope` as one of its values.
|
||||
|
||||
```js
|
||||
const iframeEl = document.querySelector('iframe')
|
||||
const iframeElAllowAttr = iframeEl?.getAttribute('allow')
|
||||
const gyroscope = iframeElAllowAttr.trim().split(' ')[4]
|
||||
assert.strictEqual(gyroscope, 'gyroscope')
|
||||
```
|
||||
|
||||
The `allow` attribute of your `iframe` element should have `web-share` as one of its values.
|
||||
|
||||
```js
|
||||
const iframeEl = document.querySelector('iframe')
|
||||
const iframeElAllowAttr = iframeEl?.getAttribute('allow')
|
||||
const webShare = iframeElAllowAttr.trim().split(' ')[5]
|
||||
assert.strictEqual(webShare, 'web-share')
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Display Videos in an iframe</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>iframe Video Display</h1>
|
||||
--fcc-editable-region--
|
||||
<iframe
|
||||
width="560"
|
||||
height="315"
|
||||
src="https://www.youtube.com/embed/I0_951_MPE0"
|
||||
allow="accelerometer autoplay clipboard-write"
|
||||
>
|
||||
|
||||
</iframe>
|
||||
--fcc-editable-region--
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
id: 68ba9c4f1688914d72876098
|
||||
title: Step 7
|
||||
challengeType: 0
|
||||
dashedName: step-7
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The next attribute you'll add is `referrerpolicy`. It is the rule that determines how much detail you share when your page connects to another page.
|
||||
|
||||
Add the `referrerpolicy` attribute and set it to `strict-origin-when-cross-origin`. This shares the full address on the same site, only the site name on other sites, and nothing on insecure sites.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `iframe` element should have a `referrerpolicy` attribute set to `strict-origin-when-cross-origin`.
|
||||
|
||||
```js
|
||||
const iframeEl = document.querySelector('iframe')
|
||||
assert.equal(iframeEl?.getAttribute('referrerpolicy'), 'strict-origin-when-cross-origin')
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Display Videos in an iframe</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>iframe Video Display</h1>
|
||||
--fcc-editable-region--
|
||||
<iframe
|
||||
width="560"
|
||||
height="315"
|
||||
src="https://www.youtube.com/embed/I0_951_MPE0"
|
||||
allow="accelerometer autoplay clipboard-write encrypted-media gyroscope web-share"
|
||||
>
|
||||
|
||||
</iframe>
|
||||
--fcc-editable-region--
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@@ -0,0 +1,78 @@
|
||||
---
|
||||
id: 68ba9c4f1688914d72876099
|
||||
title: Step 8
|
||||
challengeType: 0
|
||||
dashedName: step-8
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Last but not least, the attribute you will add is `allowfullscreen`. As it implies, it allows the video to be viewed in full screen mode.
|
||||
|
||||
With that, the workshop is completed!
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `iframe` element should have a `allowfullscreen` attribute.
|
||||
|
||||
```js
|
||||
const iframeEl = document.querySelector('iframe')
|
||||
assert.exists(iframeEl?.getAttribute('allowfullscreen'))
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Display Videos in an iframe</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>iframe Video Display</h1>
|
||||
--fcc-editable-region--
|
||||
<iframe
|
||||
width="560"
|
||||
height="315"
|
||||
src="https://www.youtube.com/embed/I0_951_MPE0"
|
||||
allow="accelerometer autoplay clipboard-write encrypted-media gyroscope web-share"
|
||||
referrerpolicy="strict-origin-when-cross-origin"
|
||||
|
||||
>
|
||||
|
||||
</iframe>
|
||||
--fcc-editable-region--
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Display Videos in an iframe</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>iframe Video Display</h1>
|
||||
<br />
|
||||
<iframe
|
||||
width="560"
|
||||
height="315"
|
||||
src="https://www.youtube.com/embed/I0_951_MPE0"
|
||||
allow="accelerometer autoplay clipboard-write encrypted-media gyroscope web-share"
|
||||
referrerpolicy="strict-origin-when-cross-origin"
|
||||
allowfullscreen
|
||||
>
|
||||
</iframe>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "Build a Video Display Using iframe",
|
||||
"isUpcomingChange": false,
|
||||
"dashedName": "workshop-build-a-video-display-using-iframe",
|
||||
"helpCategory": "HTML-CSS",
|
||||
"blockType": "workshop",
|
||||
"blockLayout": "challenge-grid",
|
||||
"challengeOrder": [
|
||||
{ "id": "68b94f23f7b3ee14078c89c5", "title": "Step 1" },
|
||||
{ "id": "68ba9c4f1688914d72876093", "title": "Step 2" },
|
||||
{ "id": "68ba9c4f1688914d72876094", "title": "Step 3" },
|
||||
{ "id": "68ba9c4f1688914d72876095", "title": "Step 4" },
|
||||
{ "id": "68ba9c4f1688914d72876096", "title": "Step 5" },
|
||||
{ "id": "68ba9c4f1688914d72876097", "title": "Step 6" },
|
||||
{ "id": "68ba9c4f1688914d72876098", "title": "Step 7" },
|
||||
{ "id": "68ba9c4f1688914d72876099", "title": "Step 8" }
|
||||
],
|
||||
"usesMultifileEditor": true,
|
||||
"hasEditableBoundaries": true
|
||||
}
|
||||
@@ -20,6 +20,7 @@
|
||||
"lecture-working-with-images-and-svgs",
|
||||
"workshop-build-a-heart-icon",
|
||||
"lecture-working-with-media",
|
||||
"workshop-build-a-video-display-using-iframe",
|
||||
"lab-video-compilation-page",
|
||||
"lecture-working-with-links",
|
||||
"review-basic-html",
|
||||
|
||||
Reference in New Issue
Block a user