Estuve un buen rato arreglando un problema de que no se mostraba el ad, todo estaba bien, había seguidotodos los pasos, pero no salía, ¿adivinen cómo lo arreglé?
Introducción
¿Qué significa ser un profesional de JavaScript?
Aspectos que destacan a un profesional
Inicio del proyecto
Repaso de Conceptos Fundamentales
Cómo llega un script al navegador
Scope
Closures
El primer plugin
this
Los métodos call, apply y bind
Prototype
Herencia Prototipal
Cómo funciona JavaScript
Parsers y el Abstract Syntax Tree
Abstract Syntax Tree en Práctica
Cómo funciona el JavaScript Engine
Event Loop
Fundamentos Intermedios
Promesas
Getters y setters
Fundamentos Avanzados
Proxy
Generators
APIs del DOM
Fetch - Cómo cancelar peticiones
IntersectionObserver
VisibilityChange
Service Workers
TypeScript
Introducción
Tipos básicos
Funciones
Interfaces
Clases
Convertir el proyecto a TypeScript
Patrones de Diseño
Qué es un patrón de diseño
Categorías de patrones de diseño
Patrón Singleton y Casos de Uso
Implementación del patrón Singleton
¿Cómo funciona el Patrón Observer?
Implementación del patrón Observer
Casos de Uso del patrón Observer: Redux
Patrón Decorator y Casos de Uso
Implementación del patrón Decorator
Proyecto: MediaPlayer
Implementación de plugin de Ads: Desplegando en consola
Implementación de plugin de Ads: Desplegando en pantalla
Publicar en npm
Conclusiones
Conclusiones
Aún no tienes acceso a esta clase
Crea una cuenta y continúa viendo este curso
Aportes 89
Preguntas 12
Estuve un buen rato arreglando un problema de que no se mostraba el ad, todo estaba bien, había seguidotodos los pasos, pero no salía, ¿adivinen cómo lo arreglé?
adsContainer:
this.adsContainer.innerHTML = ` <div class="ads">
<a class="ads__link" href="${this.currentAd.url}" target="_blank">
<img class="ads__img" src="${this.currentAd.imageUrl}" />
<div class="ads__info">
<h5 class="ads__title">${this.currentAd.title}</h5>
<p class="ads__body">${this.currentAd.body}</p>
</div>
</a>
</div>`;
Para los que se les ve el Ad debajo del vídeo y no dentro: Deben agregar a los estilos:
.ads {
padding: 4px;
padding-right: 8px;
background: white;
width: 80%;
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
}
.ads__link {
display: flex;
color: inherit;
text-decoration: inherit;
}
.ads__img {
width: 80px;
min-width: 80px;
height: 80px;
margin-right: 16px;
}
.ads__info {
display: flex;
flex-direction: column;
justify-content: center;
}
.ads__title {
margin: 0;
}
.ads__body {
margin: 0;
}
Desactiven al addBlocker y agreguen el css de los Ads !
Me tocara repetir el curso o ver otros materiales para entender mejor
Tengo pensado hacer muchas cosas con este plugin 😂
El método Node.insertBefore()
inserta un nodo antes del nodo de referencia como hijo de un nodo padre indicado. Si el nodo hijo es una referencia a un nodo ya existente en el documento, insertBefore()
lo mueve de la posición actual a la nueva posición (no hay necesidad de eliminar el nodo de su nodo padre antes de agregarlo al algún nodo nuevo).
Esto significa que el nodo no puede estar en dos puntos del documento al simultáneamente. Por lo que si el nodo ya tiene un padre, primero se elimina el nodo, y luego se inserta en la nueva posición. Node.cloneNode()
puede utilizarse para hacer una copia de un nodo antes de insertarlo en un nuevo padre. Ten en cuenta que las copias hechas con cloneNode()
no se mantendrán sincronizadas automáticamente.
Si el nodo de referencia es null
, el nodo indicado se añadirá al final de la lista de hijos del nodo padre especificado.
Si el hijo proporcionado es un DocumentFragment
, el contenido completo del DocumentFragment
se moverá a la lista de hijos del nodo padre indicado.
var _insertedNode_ = _parentNode_.insertBefore(_newNode_, _referenceNode_);
insertedNode
El nodo que esta siendo insertado, es decir, newNode
parentNode
El padre del nodo recién insertado.newNode
El nodo a insertar.referenceNode
El nodo antes del cual se inserta newNode
.Si referenceNode
es null
, el newNode
se insertará al final de la lista de nodos hijos.
referenceNode
no es un parámetro opcional – debes pasar explícitamente un Node
o null
. No proporcionándolo o pasando valores no válidos podría provocar un comportamiento distinto en diferentes versiones de navegadores.
El valor devuelto es el hijo añadido excepto cuando newNode
es un DocumentFragment
, en cuyo caso se devuelve un DocumentFragment
.
La propiedad Element.innerHTML
devuelve o establece la sintaxis HTML describiendo los descendientes del elemento.
Al establecerse se reemplaza la sintaxis HTML del elemento por la nueva.
Nota: Si un nodo tiene un texto secundario que incluye los caracteres (&), (<),
o (>)
, innerHTML
devuelve estos caracteres como &, < y > respectivamente. Use Node.textContent
para conseguir una copia correcta del contenido de estos nodos de texto.
Para insertar el código HTML en el documento en lugar de cambiar el contenido de un elemento, use el método insertAdjacentHTML().
Estuve unos 20 minutos buscando el porque no se me mostraba los datos aunque aparecia el div y era porque tenia el uBlockOrigin activo 🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣
Exito. 100% Real no fake 😃
Por si lo necesitan
private renderAd(){
if (this.currentAd) {
return
}
const ad = this.ads.getAd()
this.currentAd = ad
this.adsContainer.innerHTML = `
<div class="ads">
<a class="ads__link" href="${this.currentAd.url}" target="_blank">
<img class="ads__img" src="${this.currentAd.imageUrl}" />
<div class="ads__info">
<h5 class="ads__title">${this.currentAd.title}</h5>
<p class="ads__body">${this.currentAd.body}</p>
</div>
</a>
</div>
`
}
Uhh genial, todo me funcionó bien expeto… que no se de dónde agarrar los estilos xD Me aparecen los ads debajo del video pero todo bien jaja
Después de un rato repasando el curso y leer el media API puede terminar un reproductor bastante básico, les muestro mi resultado final.
El repositorio: https://github.com/darkOwlWood/MediaPlayer
El sitio web: https://ecstatic-mclean-b27f5d.netlify.app/
PD: En celulares no sirve también ya que no uso eventos touch :p .
<div class="ads">
<a class="ads__link" href="${this.currentAd.url}" target="_blank">
<img class="ads__img" src="${this.currentAd.imageUrl}" />
<div class="ads__info">
<h5 class="ads__title">${this.currentAd.title}</h5>
<p class="ads__body">${this.currentAd.body}</p>
</div>
</a>
</div>
Que increible, pero que desilución que el media player tenga controles jajaja, mis botones ahora no sirven para mucho :c
Estuve como 10 minutos buscando porque no se mostraban los ads así que decidí leer los comentarios a ver si alguno le pasaba y leí que tenían activado el addBlock… advienen a quien le paso lo mismo .-.
Yo pensando hacerlo con html y css, pero aqui a PELO nivel hard
#NuncaParesDeAprender
Alguien sabe como hizo el profe para que se muestre el control para adelantar el video?
SI tienen AdBlocker Los ads No se ven, Una hora tratando de arreglar eso, por no leer comentarios
Estuve un par de horas viendo porqué no me aparecía el anuncio de nuevo luego de los 10 segundos… era porque el vídeo que agregué duraba 28 segundos 🤣🤣
AdsContainer
<div class="ads">
<a class="ads__links" href="${this.currentAd.url}" target="_blank">
<img class="ads__img" src="${this.currentAd.imageUrl}"/>
<div class="ads__info">
<h5 class="ads__title">${this.currentAd.title}</h5>
<p class="ads__body">${this.currentAd.body}</p>
</div>
</a>
</div>
private renderAd(){
if(this.currentAdd){
return;
}
const ad = this.ads.getAd();
this.currentAdd = ad;
this.adsContainer.innerHTML = `
<div class="ads">
<a class="ads__link" href="${this.currentAdd.url}" target="_blank">
<img class="ads__img" src="${this.currentAdd.imageUrl}" />
<div class="ads__info">
<h5 class="ads__title">${this.currentAdd.title}</h5>
<p class="ads__body">${this.currentAdd.body}</p>
</div>
</a>
</div>
`;
setTimeout(() => {
this.currentAdd = null;
this.adsContainer.innerHTML = '';
},
10000);
}
Tal cual, el codigo de los estilos del contenedir de los ads:
* {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
box-sizing: border-box;
}
body {
background: #eeeeee;
color: #030303;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
header {
text-align: center;
padding: 3rem 0;
background-image: linear-gradient(120deg, #f093fb 0%, #f5576c 100%);
color: white;
}
header > h1 {
font-weight: normal;
font-style: italic;
}
main {
padding: 1rem 0;
}
.container {
max-width: 960px;
width: 100%;
margin: 0 auto;
}
.movie {
width: 100%;
}
.ads {
padding: 4px;
padding-right: 8px;
background: white;
width: 80%;
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
}
.ads__link {
display: flex;
color: inherit;
text-decoration: inherit;
}
.ads__img {
width: 80px;
min-width: 80px;
height: 80px;
margin-right: 16px;
}
.ads__info {
display: flex;
flex-direction: column;
justify-content: center;
}
.ads__title {
margin: 0;
}
.ads__body {
margin: 0;
}
funciono después de quitar el adblock xd
Creo que a varios les pudo ocurrir que la etiqueta a del hipervínculo en el container no tenía el cierre ‘>’ lo cual ocasionaba que no se mostrara la imagen en el banner del ad.
Alguien sabe porque si se ven mis Ads pero se ven abajo del video y no sobre el video?
Después de pasar días con este error, por fin pude solucionar
La última actualización de Babel está generando errores en el intercambio de datos con parcel-bundler.
Referencia => Aquí
Seguí muchos pasos que indican los compañeros ahí, pero ninguno me ayudó. Al final la unica solución que encontré, fue copiar un proyecto anterior (donde si me levantaba el servidor tranquilamente) y llevar los archivos de este proyecto para la nueva copia.
Lo que se me hace extraño es que en el proyecto anterior si corre, en el proyecto nuevo intenté replicar la configuración y no me permite levantar el servidor, solo encontré solución copiando el proyecto antiguo.
Mucho texto, pero dejo esto aquí por si alguien está sufriendo con este error.
En el navegador Firefox si me funciona pero en Chrome no! 😫
Sólo se me ve una línea blanca… A alguien más le pasa?
Esta super genial este curso, me agrada mucho el resultado
jajaja horas revisando mi código viendo por que mis anuncios salían por debajo del video y no sobre el video hasta que revise el css del los archivos del enlace me di cuenta que habían estilos que no tenia.
Hola, tengo el siguiente error en consola, si bien entiendo cuál es el problema, no logro solucionarlo.
Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause(). https://goo.gl/LdLk22
¿Alguien puede ayudarme?
Les comparto la liga donde estoy tranajando la practica, todo lo arme en CodeSanbox
Me pasó algo interesante y no quiero que les pase. Cuando llaman los métodos de inicialización, asegúrence de inicializar primero el de _initPlayer() de otra forma no verán los div generados desde código.
Acá vamos, mucho contenido, mucho que aprender. Continuemos
este curso fue dificil y muchos veces bastante confuso, pero nucna habia aprendido tanto 😃 #neverStopLearning
Modicaciones de los archivos:
Assets/plugins/Ads/Index.ts:
constructor() {
this.ads = Ads.getInstance();
this.adsContainer = document.createElement('div');
}
run(player: MediaPlayer){
this.player = player;
this.player.container.appendChild(this.adsContainer);
this.media = this.player.media;
this.media.addEventListener('timeupdate',this.handlerTimeUpdate);
}
private renderAd(){
if(this.currentAd) return;
const ad = this.ads.getAd();
this.currentAd = ad;
this.adsContainer.innerHTML = `
<div class="ads">
<a class="ads__link" href="${this.currentAd.url}" target="_blank">
<img class="ads__img" src="${this.currentAd.imageUrl}" />
<div class="ads__info">
<h5 class="ads__title">${this.currentAd.title}</h5>
<p class="ads__body">${this.currentAd.body}</p>
</div>
</a>
</div>
`;
setTimeout(
()=>{
this.currentAd = null;
this.adsContainer.innerHTML = ``;
},
10000
)
}
Pero que belleza este curso :’)
Este curso es una joyita
Si no les sale el contenedor de avisos encima del video aca les dejo los estilos:
.ads {
padding: 2px;
background: rgba(255, 255, 255, 0.3);
inline-size: 80%;
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
}
.ads__link {
text-decoration: none;
color: #030303;
display: flex;
align-items: center;
}
.ads__link > img {
block-size: 100px;
inline-size: 100px;
}
.ads__info {
margin-inline-start: 8px;
display: flex;
flex-direction: column;
justify-content: center;
}
Hice mi propia implementación del método getAd, donde utilizó el mismo array ALL_ADS y un índice para no tener que crear un array nuevo he ir haciendo pop, ya que considero que es muy costoso. El índice es circular, es decir cuando llega al ALL_ADS.length entonces vuelve a 0;
getAd(): any {
this.index = (++this.index) % this.ALL_ADS.length;
return this.ALL_ADS[this.index];
}
Wow, quien lo diria, la clase MediaPlayer usaba el patron Decorator todo este tiempo! 😂
por un momento me asuste de donde saco los controles jajaja, estupendo repase este curso tres veces es estupendo muchas gracias por todo richard 😄
Hola, no me aparece el <div> del minuto 4:44. Hasta ese momento mi HTML queda asi:
Sin embargo, al colocar la linea:
this.player.container.appendChild(this.adsContainer);
El HTML queda de este modo
JJahajaahha Que comico lo del bloqueador de anuncios, estuve 30m buscando el problema y era eso
export interface Ad {
imageUrl: string;
title: string;
body: string;
url: string;
}
const ALL_ADS: Ad[] = [
{
imageUrl:
"https://static.platzi.com/media/achievements/badge-profesional-javascript-13538df2-24ce-433f-9aa6-e34eed608e70.png",
title: "Curso Profesional de JavaScript",
body:
"Mejora tus habilidades en Javascript. Conoce Typescript y cómo puedes ocuparlo para mejorar el control de tus variables.",
url: "https://platzi.com/cursos/javascript-profesional/"
},
{
imageUrl:
"https://static.platzi.com/media/achievements/badge-frontend-developer-8a49e681-3e22-408d-b886-2f47dfc9953a.png",
title: "Curso de Frontend Developer",
body:
"Domina las bases de HTML y CSS. Define la arquitectura de tu código y construye un sitio web usando componentes estáticos. ",
url: "https://platzi.com/cursos/frontend-developer/"
},
{
imageUrl:
"https://static.platzi.com/media/achievements/badge-backend-node-8e6aa8a9-f7cd-42b7-bf4a-e1ee916a942b.png",
title: "Curso de Backend con Node.js",
body:
"Crea aplicaciones backend utilizando Node.js, Express y Mongo. Entiende cómo funciona Javascript en un servidor y escribe aplicaciones con Node.js.",
url: "https://platzi.com/cursos/backend-nodejs/"
},
{
imageUrl:
"https://static.platzi.com/media/achievements/badge-prework-da6b0493-9908-40f3-ad53-f5d330b995b8.png",
title:
"Comienza tus proyectos de desarrollo para JavaScript configurando un entorno de desarrollo cómodo y adaptado a tus necesidades.",
body:
"Mejora tus habilidades en Javascript. Conoce Typescript y cómo puedes ocuparlo para mejorar el control de tus variables.",
url: "https://platzi.com/cursos/prework/"
},
{
imageUrl:
"https://static.platzi.com/media/achievements/badge-autenticacion-passport-6d45426a-2b24-4757-8927-7bfaf54529dd.png",
title: "Curso de Autenticación con Passport.js",
body:
"Genera estrategias de autenticación Sign-In y Sign-Out usando Passport.js. Agrega autenticación con Facebook, Twitter y Google a tus desarrollos.",
url: "https://platzi.com/cursos/passport/"
},
{
imageUrl:
"https://static.platzi.com/media/achievements/badge-backend-frontend-02b2ac18-331a-4959-85bf-0bd3c2aa009c.png",
title: "Curso de Backend for Frontend",
body:
"La ingeniería de software evoluciona día a día, no te quedes atrás. Ahora que eres un Desarrollador FullStack JavaScript necesitas evolucionar con el software, construye arquitecturas de software modernas.",
url: "https://platzi.com/cursos/bff/"
},
{
imageUrl:
"https://static.platzi.com/media/achievements/badge-react-adec89d0-1c35-4c9c-847e-18c284dc79dd.png",
title: "Curso Práctico de React JS",
body:
"React es una de las librerías más utilizadas hoy para crear aplicaciones web. Aprende a través de la creación de la interfaz de PlatziVideo todo lo que necesitas para crear increíbles componentes con React. ",
url: "https://platzi.com/cursos/react-ejs/"
},
{
imageUrl:
"https://static.platzi.com/media/achievements/badge-react-redux-2ca3c0a5-fc53-437f-bfba-69e9ddd5a803.png",
title: "Curso de React Router y Redux",
body:
"Aprende de forma práctica a implementar React Router para manejar rutas en tus proyectos de frontend como un profesional.",
url: "https://platzi.com/cursos/react-router-redux/"
}
];
class Ads {
private static instance: Ads;
private ads: Ad[];
private constructor() {
this.initAds();
}
static getInstance() {
if (!Ads.instance) {
Ads.instance = new Ads();
}
return Ads.instance;
}
private initAds() {
this.ads = [...ALL_ADS];
}
getAd() {
if (this.ads.length === 0) {
this.initAds();
}
return this.ads.pop();
}
}
export default Ads;
Se puede concluir que los plugins son una forma de implementar el patron decorator ?
estoy muy emocionado ahhhhhhhhhhh
pero una cosa, al renderizar el ad, a veces se puede ver como el html se intenta acomodar, hay alguna forma de optiizar nuestro código para que esto no pase?
genial
A pesar de que descargué el index.css del proyecto final, me aparece así el ad
Me sucede algo muy curioso, tengo el código igual, (obvio pueden haber algunos errores nunca faltan)
Pero lo que sucede es que tengo el html en el inspector igual a Richard,(con los div donde deben estar) pero a la hora de que los Ads aparezcan el div contenedor se amplía, luego cuando acaba el tiempo del Ads vuelve a su valor usual.
Super útil
Excelente clase!!
Por fin terminado!! :DD
Comparto mi MediaPlayer, tengo muchas ideas para hacerle cambios jeje
Super genial 😃
Wauu me gustó mucho este proyecto.
Super útil eso
Muy buen curso, muy útil!!!
WOW qué genial esto.
Por qué en este ejercicio no utilizó nextSibling al momento de usar insertBefore, como en el index.ts de decorator?
Hola, no me aparece el <div> del minuto 4:44. Hasta ese momento mi HTML quedas así:

Sin embargo, al colocar la linea
this.player.container.appendChild(this.adsContainer);
El HTML queda de este modo:

Muy interesante, tenemos que tener en cuenta que a través de los plugins podemos extender la funcionalidad base de MediaPlayer, sin necesidad de meternos en su código interno.
class Ads {
private static instance: Ads;
private ads: Ad[];
private constructor() {
this.initAds();
}
static getInstance() {
if(!Ads.instance) {
Ads.instance = new Ads();
}
return Ads.instance;
}
private initAds() {
this.ads = [...ALL_ADS];
}
getAd() {
if(this.ads.length === 0) {
this.initAds();
}
return this.ads.pop();
}
}
export default Ads;
Que maravilloso curso!!!
Si dan click derecho en el reproductor de platzi, tambien muestra los controles predefinidos por HTML5…
Yo quería hacer los controles personalizados, pero con esto, ya tenemos la base para lograrlo, si alguien quiere desarrollar el resto de controles, comenten para poder hacerlo…
Puede ser una excelente practica para todos 😄
Excelente!
Súper!
Quede fue loco!
A alguien más le salen 3 divs?
Por qué?
alguien más tiene este problema? Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause().
Súpeeeer. Gracias!!
Super Genial !!!
No entiendo el import del Ads, la ruta que especifica “./plugins/Ads” no hace referencia a una carpeta???
Por otro lado, hace “new Ads()” cuando el constructor es privado.
Con una importación ya obtiene las exportaciones de dos archivos de la carpeta???
😄
Hola!, Cree una solución un tanto distinta, con un botón para cerrar los anuncios, les comparto el código por si alguien le quiere echar un ojo 😄
Otra forma de evitar el bloqueo de ads es cambiar el nombre de las clases de las etiquetas de html. Yo las renombré de ads a pub ‘publicidad’. Después de esto, logré ver los banner con el adblocker activado.
Adjunto el index.css (al nivel de MediaPlayer.ts)
* {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
box-sizing: border-box;
}
body {
background: #eeeeee;
color: #030303;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
header {
text-align: center;
padding: 3rem 0;
background-image: linear-gradient(120deg, #f093fb 0%, #f5576c 100%);
color: white;
}
header > h1 {
font-weight: normal;
font-style: italic;
}
main {
padding: 1rem 0;
}
.container {
max-width: 960px;
width: 100%;
margin: 0 auto;
}
.movie {
width: 100%;
}
.ads {
padding: 4px;
padding-right: 8px;
background: white;
width: 80%;
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
}
.ads__link {
display: flex;
color: inherit;
text-decoration: inherit;
}
.ads__img {
width: 80px;
min-width: 80px;
height: 80px;
margin-right: 16px;
}
.ads__info {
display: flex;
flex-direction: column;
justify-content: center;
}
.ads__title {
margin: 0;
}
.ads__body {
margin: 0;
}
Justo estoy haciendo una páina para una agrupación de baile, me cae a pelo para que parezca más profesional
muy pro este profe, un par de veces más este curso para acercarme algo a tener sus conocimientos xd
esta clase fue super mega buena, quede como con un hambre de hacer el curso de manipulacion del dom. y de react ajajaja
muy interesante este capitulo.
Vamos!! 😀
se cayeron los links de la imágenes de los ads
<div class=“ads”>
<a class=“ads__links” href="${this.currentAd.url}" target="_blank">
<img class=“ads__img” src="${this.currentAd.imageUrl}"/>
<div class=“ads__info”>
<h5 class=“ads__title”>${this.currentAd.title}</h5>
<p class=“ads__body”>${this.currentAd.body}</p>
</div>
</a>
</div>
Excelente Curso! El mejor que he visto en Platzi.
Que pro.
Buena clase.
,
¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.