├── .gitignore ├── 01 ├── README.md ├── background.png ├── index.html ├── main.css ├── main.css.map ├── main.js └── main.scss ├── 02 ├── .sass-cache │ └── 7c83e4963bce4f44bd9edcdb9a4b6088c05d5c83 │ │ └── main.scssc ├── README.md ├── index.html ├── main.css ├── main.css.map ├── main.js └── main.scss ├── 03 ├── README.md ├── index.html ├── main.css ├── main.css.map ├── main.js └── main.scss ├── 04 ├── README.md ├── index.html ├── main.css ├── main.css.map ├── main.js └── main.scss ├── 05 ├── index.html └── main.js ├── 06 ├── .sass-cache │ └── b6be92afc40273d12b45568cc6bf33d9d9bf73ea │ │ └── main.scssc ├── getData.js ├── index.html ├── loading.gif ├── main.css ├── main.css.map ├── main.js └── main.scss ├── 07 ├── index.html ├── main.css └── main.js └── 08 ├── README.md ├── index.html ├── main.css ├── main.css.map ├── main.js └── main.scss /.gitignore: -------------------------------------------------------------------------------- 1 | .sass-cache/ 2 | .DS_store 3 | -------------------------------------------------------------------------------- /01/README.md: -------------------------------------------------------------------------------- 1 | # Exercicio 01 2 | 3 | > https://codepen.io/brizental/pen/qYLQjN 4 | 5 | O objetivo desse exercicio era adicionar o javascript para tornar esse app de lista de tarefas interativo. Quando o usuario adicionasse um nove texto ao input e submetesse o formulario, o input deveria ser resetado e o texto adicionado deveria se tornar uma nova tarefa na lista. Quando uma tarefa da lista fosse cliacada, ela deveria aparecer com uma cor mais clara e um risco no meio. -------------------------------------------------------------------------------- /01/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brizental/reprograma-javascript/546e37dfb5508033382b34b899b654ecea3f4ba3/01/background.png -------------------------------------------------------------------------------- /01/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tarefas 6 | 7 | 8 | 9 | 10 |
11 |
12 | 13 |
14 | 16 |
17 | 18 | 19 | -------------------------------------------------------------------------------- /01/main.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | font-family: 'Raleway', sans-serif; 4 | letter-spacing: 1px; 5 | } 6 | 7 | body { 8 | background-image: url("./background.png"); 9 | background-size: cover; 10 | overflow: hidden; 11 | height: 100vh; 12 | padding: 0; 13 | margin: 0; 14 | } 15 | 16 | #container { 17 | margin: 100px auto; 18 | background-color: white; 19 | box-shadow: 0px 0px 62px -19px white; 20 | height: calc(100vh - 200px); 21 | overflow-y: auto; 22 | width: 25vw; 23 | } 24 | 25 | #input { 26 | position: relative; 27 | border-bottom: 1px solid #eaeaea; 28 | } 29 | 30 | #input input[type="text"] { 31 | width: 100%; 32 | border: none; 33 | border-radius: none; 34 | padding: 50px; 35 | font-size: 16px; 36 | color: #aeaeae; 37 | } 38 | 39 | #input input[type="submit"] { 40 | position: absolute; 41 | background: transparent; 42 | border-radius: 0; 43 | border: none; 44 | right: 0; 45 | } 46 | 47 | #list { 48 | padding: 0; 49 | margin: 0; 50 | list-style-type: none; 51 | } 52 | 53 | #list li { 54 | padding: 10px 50px; 55 | border-bottom: 1px solid #eaeaea; 56 | transition: background-color 300ms; 57 | cursor: pointer; 58 | display: flex; 59 | justify-content: space-between; 60 | align-items: center; 61 | } 62 | 63 | #list li p.done { 64 | color: #aeaeae; 65 | text-decoration: line-through; 66 | cursor: initial; 67 | } 68 | 69 | #list li p.done:hover { 70 | background-color: white; 71 | } 72 | 73 | #list li .delete { 74 | margin-left: 2rem; 75 | } 76 | 77 | #list li:hover { 78 | background-color: #f0f0f0; 79 | } 80 | /*# sourceMappingURL=main.css.map */ -------------------------------------------------------------------------------- /01/main.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "mappings": "AAAA,AAAA,CAAC,CAAC;EACA,UAAU,EAAE,UAAU;EACtB,WAAW,EAAE,qBAAqB;EAClC,cAAc,EAAE,GAAG;CACpB;;AAED,AAAA,IAAI,CAAC;EACH,gBAAgB,EAAE,uBAAuB;EACzC,eAAe,EAAE,KAAK;EACtB,QAAQ,EAAE,MAAM;EAChB,MAAM,EAAE,KAAK;EACb,OAAO,EAAE,CAAC;EACV,MAAM,EAAE,CAAC;CACV;;AAED,AAAA,UAAU,CAAC;EACT,MAAM,EAAE,UAAU;EAClB,gBAAgB,EAAE,KAAK;EACvB,UAAU,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAE,KAAI,CAAC,KAAmB;EAClD,MAAM,EAAE,mBAAmB;EAC3B,UAAU,EAAE,IAAI;EAChB,KAAK,EAAE,IAAI;CACZ;;AAED,AAAA,MAAM,CAAC;EACL,QAAQ,EAAE,QAAQ;EAClB,aAAa,EAAE,iBAAiB;CAoBjC;;AAtBD,AAIE,MAJI,CAIJ,KAAK,CACH,AAAA,IAAE,CAAK,MAAM,AAAX,EAAa;EACb,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,aAAa,EAAE,IAAI;EACnB,OAAO,EAAE,IAAI;EACb,SAAS,EAAE,IAAI;EACf,KAAK,EAAE,OAAO;CACf;;AAZL,AAIE,MAJI,CAIJ,KAAK,CAUH,AAAA,IAAE,CAAK,QAAQ,AAAb,EAAe;EACf,QAAQ,EAAE,QAAQ;EAClB,UAAU,EAAE,WAAW;EACvB,aAAa,EAAE,CAAC;EAChB,MAAM,EAAE,IAAI;EACZ,KAAK,EAAE,CAAC;CACT;;AAIL,AAAA,KAAK,CAAC;EACJ,OAAO,EAAE,CAAC;EACV,MAAM,EAAE,CAAC;EACT,eAAe,EAAE,IAAI;CA6BtB;;AAhCD,AAKE,KALG,CAKH,EAAE,CAAC;EACD,OAAO,EAAE,SAAS;EAClB,aAAa,EAAE,iBAAiB;EAChC,UAAU,EAAE,sBAAsB;EAClC,MAAM,EAAE,OAAO;EACf,OAAO,EAAE,IAAI;EACb,eAAe,EAAE,aAAa;EAC9B,WAAW,EAAE,MAAM;CAmBpB;;AA/BH,AAcI,KAdC,CAKH,EAAE,CASA,CAAC,AAAA,KAAK,CAAC;EACL,KAAK,EAAE,OAAO;EACd,eAAe,EAAE,YAAY;EAC7B,MAAM,EAAE,OAAO;CAKhB;;AAtBL,AAcI,KAdC,CAKH,EAAE,CASA,CAAC,AAAA,KAAK,AAKJ,MAAO,CAAC;EACN,gBAAgB,EAAE,KAAK;CACxB;;AArBP,AAwBI,KAxBC,CAKH,EAAE,CAmBA,OAAO,CAAC;EACN,WAAW,EAAE,IAAI;CAClB;;AA1BL,AAKE,KALG,CAKH,EAAE,AAuBA,MAAO,CAAC;EACN,gBAAgB,EAAE,OAAO;CAC1B", 4 | "sources": [ 5 | "main.scss" 6 | ], 7 | "names": [], 8 | "file": "main.css" 9 | } -------------------------------------------------------------------------------- /01/main.js: -------------------------------------------------------------------------------- 1 | var form = document.getElementById("input") 2 | form.addEventListener("submit", function (event) { 3 | // Nao permitir comportamento padrao do navegador 4 | event.preventDefault() 5 | // Capturar o elemento de input 6 | var todoInput = document.querySelector("#input input") 7 | // Capturar texto do input e aplicar o método trim() para tirar os espaços em branco 8 | var todoText = todoInput.value.trim() 9 | // Checar se tem texto no input 10 | if (todoText.length === 0) { 11 | todoInput.value = "" 12 | 13 | } else { 14 | // Criar novo li 15 | var newTodoItem = document.createElement("li") 16 | 17 | // Criar text que vai dentro de novo li 18 | var newTodoItemText = document.createElement("p") 19 | newTodoItemText.textContent = todoText 20 | 21 | var xDiv = document.createElement("div") 22 | xDiv.classList.add("delete") 23 | xDiv.textContent = "x"; 24 | 25 | 26 | 27 | // Colocar texto dentro do li 28 | newTodoItem.appendChild(newTodoItemText) 29 | 30 | newTodoItem.appendChild(xDiv) 31 | 32 | 33 | // Capturar elemento da lista 34 | var todoList = document.getElementById("list") 35 | // Colocar novo li dentro da lista 36 | todoList.appendChild(newTodoItem) 37 | // Escutar eventos de click no list item recem criado 38 | newTodoItem.addEventListener("click", function(event) { 39 | // Checa se o elemento ja esta marcado como feito 40 | if (newTodoItemText.classList.contains("done")) { 41 | // Caso ja esteja, marca como "nao feito" 42 | newTodoItemText.classList.remove("done") 43 | } else { 44 | // Caso nao esteja marca como "feito" 45 | newTodoItemText.classList.add("done") 46 | } 47 | }) 48 | 49 | xDiv.addEventListener("click", function (event) { 50 | newTodoItem.remove(newTodoItem) 51 | }) 52 | 53 | // Limpar meu input 54 | todoInput.value = "" 55 | } 56 | }) -------------------------------------------------------------------------------- /01/main.scss: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | font-family: 'Raleway', sans-serif; 4 | letter-spacing: 1px; 5 | } 6 | 7 | body { 8 | background-image: url('./background.png'); 9 | background-size: cover; 10 | overflow: hidden; 11 | height: 100vh; 12 | padding: 0; 13 | margin: 0; 14 | } 15 | 16 | #container { 17 | margin: 100px auto; 18 | background-color: white; 19 | box-shadow: 0px 0px 62px -19px rgba(255,255,255,1); 20 | height: calc(100vh - 200px); 21 | overflow-y: auto; 22 | width: 25vw; 23 | } 24 | 25 | #input { 26 | position: relative; 27 | border-bottom: 1px solid #eaeaea; 28 | 29 | input { 30 | &[type="text"] { 31 | width: 100%; 32 | border: none; 33 | border-radius: none; 34 | padding: 50px; 35 | font-size: 16px; 36 | color: #aeaeae; 37 | } 38 | 39 | &[type="submit"] { 40 | position: absolute; 41 | background: transparent; 42 | border-radius: 0; 43 | border: none; 44 | right: 0; 45 | } 46 | } 47 | } 48 | 49 | #list { 50 | padding: 0; 51 | margin: 0; 52 | list-style-type: none; 53 | 54 | li { 55 | padding: 10px 50px; 56 | border-bottom: 1px solid #eaeaea; 57 | transition: background-color 300ms; 58 | cursor: pointer; 59 | display: flex; 60 | justify-content: space-between; 61 | align-items: center; 62 | 63 | p.done { 64 | color: #aeaeae; 65 | text-decoration: line-through; 66 | cursor: initial; 67 | 68 | &:hover { 69 | background-color: white; 70 | } 71 | } 72 | 73 | .delete { 74 | margin-left: 2rem; 75 | } 76 | 77 | &:hover { 78 | background-color: #f0f0f0; 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /02/.sass-cache/7c83e4963bce4f44bd9edcdb9a4b6088c05d5c83/main.scssc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brizental/reprograma-javascript/546e37dfb5508033382b34b899b654ecea3f4ba3/02/.sass-cache/7c83e4963bce4f44bd9edcdb9a4b6088c05d5c83/main.scssc -------------------------------------------------------------------------------- /02/README.md: -------------------------------------------------------------------------------- 1 | # Exercicio 02 2 | 3 | > https://codepen.io/brizental/pen/QrzJpZ 4 | 5 | O objetivo desse exercicio era usar o objeto `appointments` do javascript para criar o HMTL que mostra o conteudo dele para o usuario. Alem disso, um desafio era pintar somente a bolinha do horario mais proximo do horario atual de vermelho. -------------------------------------------------------------------------------- /02/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Document 6 | 7 | 8 | 9 | 10 |
11 |
12 | 16 |
17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /02/main.css: -------------------------------------------------------------------------------- 1 | *{box-sizing:border-box;font-family:'Roboto', sans-serif}h1,h2{font-weight:900;margin:0;padding:0}p{font-weight:300;color:#aeaeae;margin:0;padding:0}body{position:relative;margin:0}#overlay{position:absolute;z-index:999;bottom:0;height:150px;width:100%;background-color:yellow;background:linear-gradient(to bottom, rgba(255,255,255,0) 0%, #fff 74%, #fff 100%)}#container{padding:30px}#header{margin-bottom:50px}#header h1{margin-bottom:10px}#schedule .appointment{display:flex;align-items:flex-start;position:relative}#schedule .appointment:last-child .event{padding-bottom:70px}#schedule .appointment .circle{position:absolute;background-color:white;border-radius:100%;border:2px solid red;left:calc(25% - 5px);top:-5px;width:12px;height:12px}#schedule .appointment .time{width:25%;margin-top:-8px;text-align:right;padding-right:20px}#schedule .appointment .event{padding:30px 0 30px 25px;border-left:2px solid red;width:70%} 2 | /*# sourceMappingURL=main.css.map */ 3 | -------------------------------------------------------------------------------- /02/main.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "mappings": "AAAA,CAAE,CACA,UAAU,CAAE,UAAU,CACtB,WAAW,CAAE,oBAAoB,CAGnC,KACG,CACD,WAAW,CAAE,GAAG,CAChB,MAAM,CAAE,CAAC,CACT,OAAO,CAAE,CAAC,CAGZ,CAAE,CACA,WAAW,CAAE,GAAG,CAChB,KAAK,CAAE,OAAO,CACd,MAAM,CAAE,CAAC,CACT,OAAO,CAAE,CAAC,CAGZ,IAAK,CACH,QAAQ,CAAE,QAAQ,CAClB,MAAM,CAAE,CAAC,CAGX,QAAS,CACP,QAAQ,CAAE,QAAQ,CAClB,OAAO,CAAE,GAAG,CACZ,MAAM,CAAE,CAAC,CACT,MAAM,CAAE,KAAK,CACb,KAAK,CAAE,IAAI,CACX,gBAAgB,CAAE,MAAM,CACxB,UAAU,CAAE,uEAAmG,CAGjH,UAAW,CACT,OAAO,CAAE,IAAI,CAGf,OAAQ,CACN,aAAa,CAAE,IAAI,CAEnB,UAAG,CACD,aAAa,CAAE,IAAI,CAKrB,sBAAa,CACX,OAAO,CAAE,IAAI,CACb,WAAW,CAAE,UAAU,CACvB,QAAQ,CAAE,QAAQ,CAGhB,wCAAO,CACL,cAAc,CAAE,IAAI,CAIxB,8BAAQ,CACN,QAAQ,CAAE,QAAQ,CAClB,gBAAgB,CAAE,KAAK,CACvB,aAAa,CAAE,IAAI,CACnB,MAAM,CAAE,aAAa,CACrB,IAAI,CAAE,eAAe,CACrB,GAAG,CAAE,IAAI,CACT,KAAK,CAAE,IAAI,CACX,MAAM,CAAE,IAAI,CAGd,4BAAM,CACJ,KAAK,CAAE,GAAG,CACV,UAAU,CAAE,IAAI,CAChB,UAAU,CAAE,KAAK,CACjB,aAAa,CAAE,IAAI,CAGrB,6BAAO,CACL,OAAO,CAAE,gBAAgB,CACzB,WAAW,CAAE,aAAa,CAC1B,KAAK,CAAE,GAAG", 4 | "sources": ["main.scss"], 5 | "names": [], 6 | "file": "main.css" 7 | } -------------------------------------------------------------------------------- /02/main.js: -------------------------------------------------------------------------------- 1 | var appointments = { 2 | "06h30": { 3 | "title": "HIIT", 4 | "person": "Michael Goulart" 5 | }, 6 | "07h00": { 7 | "title": "Zumba", 8 | "person": "Mariana Silva" 9 | }, 10 | "07h30": { 11 | "title": "Power Jump", 12 | "person": "Alvaro Bigaton" 13 | }, 14 | "08h00": { 15 | "title": "Fit Dance", 16 | "person": "Victor Bonifácio" 17 | }, 18 | "08h30": { 19 | "title": "Gap", 20 | "person": "Michael Goulart" 21 | }, 22 | "11h30": { 23 | "title": "Power Jump", 24 | "person": "Alvaro Bigaton" 25 | }, 26 | "11h35": { 27 | "title": "Zumba", 28 | "person": "Mariana Silva" 29 | }, 30 | "19h00": { 31 | "title": "HIIT", 32 | "person": "Victor Bonifácio" 33 | }, 34 | "19h00": { 35 | "title": "Jiu-Jitsu", 36 | "person": "Beto Almeida" 37 | }, 38 | "19h30": { 39 | "title": "Abdominal", 40 | "person": "Michael Goulart" 41 | }, 42 | "20h00": { 43 | "title": "Fit Dance", 44 | "person": "Evandro Almeida" 45 | }, 46 | "20h30": { 47 | "title": "Glúteos", 48 | "person": "Mariana Silva" 49 | } 50 | } 51 | 52 | // Cria uma variavel com o horario de agora e transforma em unix time 53 | // https://pt.wikipedia.org/wiki/Unix_time 54 | var now = (new Date()).getTime() 55 | // Cria uma variavel auxiliar, com o maior valor numérico possivel 56 | // no javascript. Isso e para podermos encontrar a menor differenca de 57 | // tempo entre todos os horarios no objeto "appointements" 58 | var smallestTimeDifference = Infinity 59 | // Cria uma variavel auxiliar para guardar o elemento da div.circle 60 | // que precisara sre pintada de vermelho apos todas as iteracoes do 61 | // nosso loop. 62 | var redCircle = undefined 63 | 64 | function createElementAndAddClass(element, classe) { 65 | // Cria novo elemento de HTML, esse elemento sera passado como argumento 66 | var el = document.createElement(element) 67 | // Caso o argumento "classe" tenha sido passado... 68 | if (typeof classe !== "undefined") { 69 | // Adiciona uma classe ao elemento criado 70 | el.classList.add(classe) 71 | } 72 | // Retorna o elemento criado 73 | return el 74 | } 75 | 76 | for (var time in appointments) { 77 | // Cria o elemento de HTML div.appointment 78 | var appointmentDiv = createElementAndAddClass("div", "appointment") 79 | 80 | // Cria o elemento de HTML div.time 81 | var timeDiv = createElementAndAddClass("div", "time") 82 | // Cria o elemento de HTML p 83 | var timeP = createElementAndAddClass("p") 84 | // Adiciona o valor de horario como texto dentro do p recem criado 85 | timeP.textContent = time 86 | // Coloca o p dentro do div.time 87 | timeDiv.appendChild(timeP) 88 | // Coloca o div.time dentro do div.appointment 89 | appointmentDiv.appendChild(timeDiv) 90 | 91 | // Cria o elemento de HTML div.circle 92 | var circleDiv = createElementAndAddClass("div", "circle") 93 | // Coloca o div.circle dentro do div.appointment 94 | appointmentDiv.appendChild(circleDiv) 95 | 96 | // Cria o elemento de HTML div.event 97 | var eventDiv = createElementAndAddClass("div", "event") 98 | // Cria o elemento de HTML H2 99 | var eventH2 = createElementAndAddClass("h2") 100 | // Coloca o titulo da atividade como texto dentro do H2 recem criado 101 | eventH2.textContent = appointments[time]['title'] 102 | // Cria o elemento de HTML p 103 | var eventP = createElementAndAddClass("p") 104 | // Coloca o nome da pessoa como texto dentro do p recem criado 105 | eventP.textContent = appointments[time]['person'] 106 | // Coloca o H2 dentro do div.event 107 | eventDiv.appendChild(eventH2) 108 | // Coloca o p dentro do div.event 109 | eventDiv.appendChild(eventP) 110 | // Coloca o div.event dentro do div.appointment 111 | appointmentDiv.appendChild(eventDiv) 112 | 113 | // Acessa o elemento div#schedule, que ja existe no nosso HTML 114 | var scheduleDiv = document.getElementById("schedule") 115 | // Coloca o div.appointment dentro do div#schedule 116 | scheduleDiv.appendChild(appointmentDiv) 117 | 118 | /** 119 | * Daqui pra baixo, vamos pintar apenas a bolinha que esta mais 120 | * proxima do horario atual de vermelho. 121 | * Lembrando que ja criamos algumas variaveis auxiliares para isso 122 | * antes de entrar dentro desse for...of loop. 123 | */ 124 | 125 | // Novamente, criamos um objecto Date, com o horario de agora. 126 | var timeAppointment = new Date() 127 | // No objeto date recem criado, mudamos a hora para a hora que o 128 | // evento dessa iteracao deveria acontecer. 129 | timeAppointment.setHours(parseInt(time.split("h")[0])) 130 | // Agora, mudamos os minutos para os minutos que o evento dessa 131 | // iteracao deveria acontecer. 132 | timeAppointment.setMinutes(parseInt(time.split("h")[1])) 133 | // Finalmente criamos uma timestamp da data recem criada 134 | // e recem modificada. 135 | timeAppointment = timeAppointment.getTime() 136 | // Encontramos o modulo da diferenca entre a data do evento e a 137 | // data de agora. Usamos o Math.abs porque nao nos importamos com o 138 | // sinal do resultado dessa subtracao, queremos apenas a quantidade 139 | // de segundos entre uma data e a outra. 140 | var timeDifference = Math.abs(timeAppointment - now) 141 | // Agora verificamos se a diferenca entre o horario do evento dessa 142 | // iteracao e o horario de agora, e menor do que a menor diferenca 143 | // encontrada ate agora... 144 | if (timeDifference < smallestTimeDifference) { 145 | // Caso seja a menor diferenca, setamos a nossa variavel que 146 | // guarda o valor da menor diferenca, para essa nova menor 147 | // diferenca encontrada. 148 | smallestTimeDifference = timeDifference 149 | // Tambem salvamos o elemento de HTML div.circle dessa iteracao 150 | // para podermos pintar ele de vermelho depois. 151 | redCircle = circleDiv 152 | } 153 | } 154 | 155 | // Depois de verificar todos os eventos e encontrar qual o mais proximo 156 | // do horario atual. Pintamos o div.circle desse envento de vermelho. 157 | redCircle.style.backgroundColor = "red" -------------------------------------------------------------------------------- /02/main.scss: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | font-family: 'Roboto', sans-serif; 4 | } 5 | 6 | h1, 7 | h2 { 8 | font-weight: 900; 9 | margin: 0; 10 | padding: 0; 11 | } 12 | 13 | p { 14 | font-weight: 300; 15 | color: #aeaeae; 16 | margin: 0; 17 | padding: 0; 18 | } 19 | 20 | body { 21 | position: relative; 22 | margin: 0; 23 | } 24 | 25 | #overlay { 26 | position: absolute; 27 | z-index: 999; 28 | bottom: 0; 29 | height: 150px; 30 | width: 100%; 31 | background-color: yellow; 32 | background: linear-gradient(to bottom, rgba(255,255,255,0) 0%,rgba(255,255,255,1) 74%,rgba(255,255,255,1) 100%); 33 | } 34 | 35 | #container { 36 | padding: 30px; 37 | } 38 | 39 | #header { 40 | margin-bottom: 50px; 41 | 42 | h1 { 43 | margin-bottom: 10px; 44 | } 45 | } 46 | 47 | #schedule { 48 | .appointment { 49 | display: flex; 50 | align-items: flex-start; 51 | position: relative; 52 | 53 | &:last-child { 54 | .event { 55 | padding-bottom: 70px; 56 | } 57 | } 58 | 59 | .circle { 60 | position: absolute; 61 | background-color: white; 62 | border-radius: 100%; 63 | border: 2px solid red; 64 | left: calc(25% - 5px); 65 | top: -5px; 66 | width: 12px; 67 | height: 12px; 68 | } 69 | 70 | .time { 71 | width: 25%; 72 | margin-top: -8px; 73 | text-align: right; 74 | padding-right: 20px; 75 | } 76 | 77 | .event { 78 | padding: 30px 0 30px 25px; 79 | border-left: 2px solid red; 80 | width: 70%; 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /03/README.md: -------------------------------------------------------------------------------- 1 | # Exercicio 03 2 | 3 | > https://codepen.io/brizental/pen/PeXxbE 4 | 5 | O objetivo desse exercicio era criar barras de progresso que seriam prenchidas de acordo com o atributo `data-percentage` de cada elemento na pagina com a classe `progress`. -------------------------------------------------------------------------------- /03/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Progresso 6 | 7 | 8 | 9 | 10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | 18 | 19 | -------------------------------------------------------------------------------- /03/main.css: -------------------------------------------------------------------------------- 1 | *{font-family:'Fira Mono', sans-serif;box-sizing:border-box;padding:0;margin:0}body{display:flex;align-items:center;height:100vh;width:100vw}h1{font-size:30px;margin-bottom:10px}#container{width:50vw;margin:0 auto}.progress{width:50vw;margin-bottom:50px}.progress div{height:5px;width:0;transition:width 2s ease-in} 2 | /*# sourceMappingURL=main.css.map */ 3 | -------------------------------------------------------------------------------- /03/main.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "mappings": "AAAA,CAAE,CACA,WAAW,CAAE,uBAAuB,CACpC,UAAU,CAAE,UAAU,CACtB,OAAO,CAAE,CAAC,CACV,MAAM,CAAE,CAAC,CAGX,IAAK,CACH,OAAO,CAAE,IAAI,CACb,WAAW,CAAE,MAAM,CACnB,MAAM,CAAE,KAAK,CACb,KAAK,CAAE,KAAK,CAGd,EAAG,CACD,SAAS,CAAE,IAAI,CACf,aAAa,CAAE,IAAI,CAGrB,UAAW,CACT,KAAK,CAAE,IAAI,CACX,MAAM,CAAE,MAAM,CAGhB,SAAU,CACR,KAAK,CAAE,IAAI,CACX,aAAa,CAAE,IAAI,CAEnB,aAAI,CACF,MAAM,CAAE,GAAG,CACX,KAAK,CAAE,CAAC,CACR,UAAU,CAAE,gBAAgB", 4 | "sources": ["main.scss"], 5 | "names": [], 6 | "file": "main.css" 7 | } -------------------------------------------------------------------------------- /03/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Temos tres funcoes que encontram uma cor randomica no CSS, 3 | * as tres funcoes sao validas e fazem, mais ou menos, 4 | * a mesma coisa de formas diferentes. 5 | */ 6 | 7 | function getRandomColor() { 8 | // Primeiro criamos uma array com todas as cores que tem 9 | // uma string reservada no CSS. 10 | var colors = ["AliceBlue", "AntiqueWhite", "Aqua", "Aquamarine", "Azure", "Beige", "Bisque", "Black", "BlanchedAlmond", "Blue", "BlueViolet", "Brown", "BurlyWood", "CadetBlue", "Chartreuse", "Chocolate", "Coral", "CornflowerBlue", "Cornsilk", "Crimson", "Cyan", "DarkBlue", "DarkCyan", "DarkGoldenRod", "DarkGray", "DarkGrey", "DarkGreen", "DarkKhaki", "DarkMagenta", "DarkOliveGreen", "Darkorange", "DarkOrchid", "DarkRed", "DarkSalmon", "DarkSeaGreen", "DarkSlateBlue", "DarkSlateGray", "DarkSlateGrey", "DarkTurquoise", "DarkViolet", "DeepPink", "DeepSkyBlue", "DimGray", "DimGrey", "DodgerBlue", "FireBrick", "FloralWhite", "ForestGreen", "Fuchsia", "Gainsboro", "GhostWhite", "Gold", "GoldenRod", "Gray", "Grey", "Green", "GreenYellow", "HoneyDew", "HotPink", "IndianRed", "Indigo", "Ivory", "Khaki", "Lavender", "LavenderBlush", "LawnGreen", "LemonChiffon", "LightBlue", "LightCoral", "LightCyan", "LightGoldenRodYellow", "LightGray", "LightGrey", "LightGreen", "LightPink", "LightSalmon", "LightSeaGreen", "LightSkyBlue", "LightSlateGray", "LightSlateGrey", "LightSteelBlue", "LightYellow", "Lime", "LimeGreen", "Linen", "Magenta", "Maroon", "MediumAquaMarine", "MediumBlue", "MediumOrchid", "MediumPurple", "MediumSeaGreen", "MediumSlateBlue", "MediumSpringGreen", "MediumTurquoise", "MediumVioletRed", "MidnightBlue", "MintCream", "MistyRose", "Moccasin", "NavajoWhite", "Navy", "OldLace", "Olive", "OliveDrab", "Orange", "OrangeRed", "Orchid", "PaleGoldenRod", "PaleGreen", "PaleTurquoise", "PaleVioletRed", "PapayaWhip", "PeachPuff", "Peru", "Pink", "Plum", "PowderBlue", "Purple", "Red", "RosyBrown", "RoyalBlue", "SaddleBrown", "Salmon", "SandyBrown", "SeaGreen", "SeaShell", "Sienna", "Silver", "SkyBlue", "SlateBlue", "SlateGray", "SlateGrey", "Snow", "SpringGreen", "SteelBlue", "Tan", "Teal", "Thistle", "Tomato", "Turquoise", "Violet", "Wheat", "White", "WhiteSmoke", "Yellow", "YellowGreen"]; 11 | // Depois criamos uma index aleatorio que pode ir de 0 até 12 | // o maior index existente na array "colors" 13 | var index = Math.floor(Math.random() * colors.length) 14 | // Finalmente retornamos o item da array colors que esta nesse index aleatorio. 15 | return colors[index] 16 | } 17 | 18 | function getRandomColorMilena() { 19 | // Primeiro criamos uma string com todos os carateres possiveis em 20 | // uma string de hex color. 21 | // https://developer.mozilla.org/pt-PT/docs/Web/CSS/color 22 | var letras = '0123456789ABCDEF' 23 | // Agora criamos uma string somente com o caractere '#'. 24 | var cor = "#" 25 | // Sabemos que uma cor em hexadecimal tem o # e mais 6 caracteres, 26 | // portanto criamos um loop que roda 6 vezes para podermos adicionar 27 | // esses seis caracteres que faltam a nossa string de cor. 28 | for (var j = 0; j < 6; j++) { 29 | // Pegamos um caractere aleatorio da string "letras" a cada iteracao 30 | // desse loop e adicionamos a string "cor". 31 | cor = cor + letras[Math.floor(Math.random() * letras.length)] 32 | } 33 | // Finalmente, retornamos a string "cor" que e um valor de cor hexadecimal. 34 | return cor 35 | } 36 | 37 | function getRandomColorBruna() { 38 | // Simplesmente, criamos um valor randomico entre 0 e 16777215 e 39 | // utilizando o metodo "toString" do numero em javascript, ele 40 | // transforma esse numero em um string hexadecimal. 41 | // https://en.wikipedia.org/wiki/Hexadecimal 42 | // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString 43 | return '#' + Math.floor(Math.random() * 16777215).toString(16); 44 | } 45 | 46 | /** 47 | * Aqui, criamos uma funcao que recebe como argumento um numero de 48 | * 0 a 100 que representa uma porcentagem e tambem um elemento de 49 | * HTML, que servira como container, para criar uma barra de progresso. 50 | */ 51 | 52 | function createProgressBar(percentage, containerDiv) { 53 | // Cria um elemento de HTML h1. 54 | const percentageH1 = document.createElement("h1") 55 | // Adiciona o valor de porcentagem passado como argumento mais 56 | // o simbolo de porcentagem como texto ao h1 recem criado. 57 | percentageH1.textContent = percentage + "%" 58 | // Coloca o h1 recem criado dentro do containerDiv passado como argumento. 59 | containerDiv.appendChild(percentageH1) 60 | 61 | // Cria um elemento div que sera a nossa barra de progresso. 62 | const progressBar = document.createElement("div") 63 | // Pinta essa barra de progresso com uma cor randomica do CSS. 64 | progressBar.style.backgroundColor = getRandomColor() 65 | // O codigo que esta dentro do setTimeout so roda depois de 100ms. 66 | // Nesse caso o 100ms vem do segundo argumento passado a funcao. 67 | setTimeout(() => { 68 | 69 | /** 70 | * Queremos que esse codigo rode apos 100ms, porque se ele rodar 71 | * assim que o codigo for executado, iniciaremos o width da nossa barra 72 | * direto com o valor desejado e isso nao permitira ao CSS fazer a 73 | * transicao/animacao da barra "crescendo" quando carregamos a pagina. 74 | * Fazendo com que esse codigo rode apenas um pouco depois do carregamento 75 | * da pagina, permitimos que a barra comece com 0px de width e depois 76 | * receba a width correta a partir da porcentagem, o que faz com que a 77 | * transicao do CSS aconteca. 78 | */ 79 | 80 | // Seta a width dessa bara de acordo com o valor de porcentagem passado. 81 | progressBar.style.width = percentage + "%" 82 | }, 100) 83 | // Coloca essa barra de progresso dentro do containerDiv. 84 | containerDiv.appendChild(progressBar) 85 | } 86 | 87 | /** 88 | * Agora que ja criamos todas as funcoes necessarias, 89 | * podemos interagir com o nosso HTML... 90 | */ 91 | 92 | // Primeiro selecionamos todos os elementos da pagina com a classe "progress" 93 | const progress = document.querySelectorAll(".progress") 94 | // Agora loopamos a array de elementos recem-criada... 95 | for (const div of progress) { 96 | // Pegar o valor que esta no atributo "data-percentage" desse elemento... 97 | const percentage = div.dataset.percentage 98 | // Usando a funcao createProgressBar, geramos o HTML necessario 99 | // para as barras de progresso. 100 | createProgressBar(percentage, div) 101 | } -------------------------------------------------------------------------------- /03/main.scss: -------------------------------------------------------------------------------- 1 | * { 2 | font-family: 'Fira Mono', sans-serif; 3 | box-sizing: border-box; 4 | padding: 0; 5 | margin: 0; 6 | } 7 | 8 | body { 9 | display: flex; 10 | align-items: center; 11 | height: 100vh; 12 | width: 100vw; 13 | } 14 | 15 | h1 { 16 | font-size: 30px; 17 | margin-bottom: 10px; 18 | } 19 | 20 | #container { 21 | width: 50vw; 22 | margin: 0 auto; 23 | } 24 | 25 | .progress { 26 | width: 50vw; 27 | margin-bottom: 50px; 28 | 29 | div { 30 | height: 5px; 31 | width: 0; 32 | transition: width 2s ease-in; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /04/README.md: -------------------------------------------------------------------------------- 1 | # Exercicio 04 2 | 3 | > https://codepen.io/brizental/pen/WJLYxK 4 | 5 | O objetivo desse exercicio era criar um slider que muda o volume da musica sendo tocada pelo nosso HTML. 6 | 7 | O Chrome mudou a sua politica de audios em abril/2018 e nao permite mais o atributo "autoplay" que e necessario para que esse exercicio funcione como esperado. Portanto, ele precisa ser aberto no Firefox. -------------------------------------------------------------------------------- /04/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Spotify 6 | 7 | 8 | 9 |
10 | 16 |
17 |
18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /04/main.css: -------------------------------------------------------------------------------- 1 | *{box-sizing:border-box;padding:0;margin:0}body{background-color:#111;width:100vw;height:100vh;align-items:center;display:flex}#slider{box-shadow:inset 0px 0px 12px 2px rgba(0,0,0,0.75);background-color:#aeaeae;border-radius:15px;height:20px;width:20vw;position:relative;margin:0 auto}#knob{border-radius:100%;box-shadow:0px 0px 5px -1px #fff;background:radial-gradient(ellipse at center, #fff 1%, #d3d3d3 100%);position:absolute;left:-18px;top:-7px;width:36px;height:36px} 2 | /*# sourceMappingURL=main.css.map */ 3 | -------------------------------------------------------------------------------- /04/main.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "mappings": "AAAA,CAAE,CACA,UAAU,CAAE,UAAU,CACtB,OAAO,CAAE,CAAC,CACV,MAAM,CAAE,CAAC,CAGX,IAAK,CACH,gBAAgB,CAAE,IAAI,CACtB,KAAK,CAAE,KAAK,CACZ,MAAM,CAAE,KAAK,CACb,WAAW,CAAE,MAAM,CACnB,OAAO,CAAE,IAAI,CAGf,OAAQ,CACN,UAAU,CAAE,uCAAuC,CACnD,gBAAgB,CAAE,OAAO,CACzB,aAAa,CAAE,IAAI,CACnB,MAAM,CAAE,IAAI,CACZ,KAAK,CAAE,IAAI,CACX,QAAQ,CAAE,QAAQ,CAClB,MAAM,CAAE,MAAM,CAGhB,KAAM,CACJ,aAAa,CAAE,IAAI,CACnB,UAAU,CAAE,qBAAoC,CAChD,UAAU,CAAE,yDAAmF,CAAI,QAAQ,CAAE,QAAQ,CACrH,IAAI,CAAE,KAAK,CACX,GAAG,CAAE,IAAI,CACT,KAAK,CAAE,IAAI,CACX,MAAM,CAAE,IAAI", 4 | "sources": ["main.scss"], 5 | "names": [], 6 | "file": "main.css" 7 | } -------------------------------------------------------------------------------- /04/main.js: -------------------------------------------------------------------------------- 1 | // Aqui, selecionamos o elemento com o id "knob" na pagina. 2 | // Esse elemento e a bolinha branca do nosso slider. 3 | const knob = document.getElementById("knob") 4 | // Aqui, selecionamos o elemento com o id "slider" na pagina. 5 | // Esse elemento e parte cinza onde a bolinha "anda" no nosso slider. 6 | const slider = document.getElementById("slider") 7 | // Aqui, selecionamos o elemento com o id "audio" na pagina. 8 | // Esse elemento nao aparece na pagina, mas e o elemento que tem a musica 9 | // que deve tocar sempre que abrimos nossa pagina. 10 | const audio = document.getElementById("audio") 11 | // Primeiramente, mudamos nosso volume para 0, 12 | // ja que ele comeca no 0 e somente ao deslizar o slider ele aumenta. 13 | audio.volume = 0 14 | 15 | // Criamos uma variavel auxiliar, para saber se o botao do mouse 16 | // esta sendo clicado ou nao. Iniciamos ela com o valor "false", 17 | // porque quando a pagina carrega, o mouse nao esta sendo clicado. 18 | let mouseClicked = false 19 | // Criamos uma variavel auxiliar para salvar a posicao do mouse 20 | // assim que o mouse foi clicado. 21 | let mouseClickedPosition = undefined 22 | // Criamos uma variavel auxiliar para salvar o valor da distancia 23 | // horizontal inicial do knob em relacao ao extremo esquerdo do slider. 24 | let knobInitialLeft = undefined 25 | 26 | // Criamos outras duas constantes que vao salvar o valor da 27 | // posicao X da extrema esquerda e extrema direita do slider. 28 | // Precisamos dessa duas constantes, porque elas e que vao limitar o 29 | // movimento do knob, ja que ele deve ficar contido dentro do slider. 30 | const sliderLeft = slider.getBoundingClientRect().left 31 | const sliderRight = slider.getBoundingClientRect().right 32 | 33 | // Escutamos pelo evento de "mousedown" no knob. 34 | // Esse evento e diferente do "click", porque ele e acionado quando 35 | // voce pressiona o mouse apenas. 36 | knob.addEventListener("mousedown", event => { 37 | // Mudamos a nossa auxiliar mouseClicked para true, ja que agora sim 38 | // o mouse esta sendo clicado. 39 | mouseClicked = true 40 | // Setamos a variavel mouseClickedPosition para a posicao X 41 | // do mouse no momento do clique. 42 | mouseClickedPosition = event.clientX 43 | // Setamos a variavel knobInitialLeft para a distancia esquerda do 44 | // knob em relacao ao extremo esquerdo do seu "pai", o slider. 45 | knobInitialLeft = knob.offsetLeft 46 | }) 47 | 48 | // Escutamos pelo evento de mousemove na pagina toda, nao somente sobre 49 | // o knob, porque independentemente do mouse estar ou nao sobre o knob, 50 | // se ele tiver sido clicado sobre o knob, queremos que ele mova o knob. 51 | document.addEventListener("mousemove", event => { 52 | // Mas so queremos que ele mova o knob, se o mouse tiver sido clicado 53 | // sobre o knob e tambem se o knob estiver dentro dos limites do slider... 54 | if (mouseClicked 55 | && event.clientX > sliderLeft 56 | && event.clientX < sliderRight) { 57 | // Caso a condicional seja satisfeita, calculamos a diferenca entre 58 | // a posicao inicial do mouse, que salvamos no evento de "mousedown", 59 | // e a posicao atual do mouse. 60 | const diffX = event.clientX - mouseClickedPosition 61 | // Finalmente, pegamos o valor inicial de left do knob + o tanto 62 | // que o mouse foi movido e setamos a propriedade left atualizada 63 | // para o knob se mover. 64 | knob.style.left = knobInitialLeft + diffX + "px" 65 | // Finalmente mapeamos essa posicao do knob em relacao ao slider 66 | // para um valor entre 0 e 1 usando uma regra de tres. 67 | const volume = (event.clientX - sliderLeft) / (sliderRight - sliderLeft) 68 | // Finalmente mudamos o volume do audio baseado na posicao do knob. 69 | audio.volume = volume 70 | } 71 | }) 72 | 73 | // Escutamos pelo evento de mouse up na pagina toda, e sempre que ele 74 | // acontecer, resetamos as nossas variaveis auxiliares para o valor 75 | // inicial delas, que e quando o knob nao esta sendo movido. 76 | document.addEventListener("mouseup", event => { 77 | mouseClicked = false 78 | mouseClickedPosition = undefined 79 | knobInitialLeft = undefined 80 | }) -------------------------------------------------------------------------------- /04/main.scss: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | padding: 0; 4 | margin: 0; 5 | } 6 | 7 | body { 8 | background-color: #111; 9 | width: 100vw; 10 | height: 100vh; 11 | align-items: center; 12 | display: flex; 13 | } 14 | 15 | #slider { 16 | box-shadow: inset 0px 0px 12px 2px rgba(0,0,0,0.75); 17 | background-color: #aeaeae; 18 | border-radius: 15px; 19 | height: 20px; 20 | width: 20vw; 21 | position: relative; 22 | margin: 0 auto; 23 | } 24 | 25 | #knob { 26 | border-radius: 100%; 27 | box-shadow: 0px 0px 5px -1px rgba(255,255,255,1); 28 | background: radial-gradient(ellipse at center, rgba(255,255,255,1) 1%,rgba(211,211,211,1) 100%); position: absolute; 29 | left: -18px; 30 | top: -7px; 31 | width: 36px; 32 | height: 36px; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /05/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Wordpress 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /05/main.js: -------------------------------------------------------------------------------- 1 | // Cria uma função que retorna uma Promise. 2 | // Essa função recebe como argumento uma URL e faz uma request HTTP 3 | // para essa URL. A Promise resolve se a request tiver sido bem sucedida 4 | // e retorna os dados da resposta da request. Se a request nao for bem 5 | // sucedida a Promise sera rejeitada. 6 | function getData(url) { 7 | return new Promise(function (resolve, reject) { 8 | // Cria uma nova request 9 | const req = new XMLHttpRequest() 10 | 11 | // Cria a request 12 | req.open('GET', url) 13 | 14 | // Captura o evento de 'onload', que é quando a 15 | // request terminou de ser executada. 16 | req.onload = function () { 17 | // Checa se o status da request é 200, 18 | // o que quer dizer que a request foi bem sucedida. 19 | if (req.status === 200) { 20 | // Resolve a Promise retornando a resposta da nossa request 21 | resolve(req.response) 22 | } else { 23 | // Rejeita a Promise retornando os status e texto da request 24 | reject(req.status + ' ' + req.statusText) 25 | } 26 | } 27 | 28 | // Captura o evento de 'onerror' caso o não tenha conseguido 29 | // fazer a request. Geralmente por não estar conectado a internet. 30 | req.onerror = function () { 31 | // Rejeita a Promise retornando a string 'Erro de conexão' 32 | reject('Erro de conexão') 33 | } 34 | 35 | // Envia a request. 36 | req.send() 37 | }) 38 | } 39 | 40 | const container = document.getElementById("container") 41 | container.innerHTML = "Carregando..." 42 | 43 | const p = getData("http://revistapolen.com/wp-json/wordpress-popular-posts/v1/popular-posts").then(function(response) { 44 | const jsonResponse = JSON.parse(response) 45 | container.innerHTML = "" 46 | for (const post of jsonResponse) { 47 | container.innerHTML = container.innerHTML + '

' + post['title']['rendered'] + '

' 48 | } 49 | }, function(error) { 50 | container.innerHTML = error 51 | }) -------------------------------------------------------------------------------- /06/.sass-cache/b6be92afc40273d12b45568cc6bf33d9d9bf73ea/main.scssc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brizental/reprograma-javascript/546e37dfb5508033382b34b899b654ecea3f4ba3/06/.sass-cache/b6be92afc40273d12b45568cc6bf33d9d9bf73ea/main.scssc -------------------------------------------------------------------------------- /06/getData.js: -------------------------------------------------------------------------------- 1 | // Cria uma função que retorna uma Promise. 2 | // Essa função recebe como argumento uma URL e faz uma request HTTP 3 | // para essa URL. A Promise resolve se a request tiver sido bem sucedida 4 | // e retorna os dados da resposta da request. Se a request nao for bem 5 | // sucedida a Promise sera rejeitada. 6 | function getData(url) { 7 | return new Promise(function (resolve, reject) { 8 | // Cria uma nova request 9 | const req = new XMLHttpRequest() 10 | 11 | // Cria a request 12 | req.open('GET', url) 13 | 14 | // Captura o evento de 'onload', que é quando a 15 | // request terminou de ser executada. 16 | req.onload = function () { 17 | // Checa se o status da request é 200, 18 | // o que quer dizer que a request foi bem sucedida. 19 | if (req.status === 200) { 20 | // Resolve a Promise retornando a resposta da nossa request 21 | resolve(req.response) 22 | } else { 23 | // Rejeita a Promise retornando os status e texto da request 24 | reject(req.status + ' ' + req.statusText) 25 | } 26 | } 27 | 28 | // Captura o evento de 'onerror' caso o não tenha conseguido 29 | // fazer a request. Geralmente por não estar conectado a internet. 30 | req.onerror = function () { 31 | // Rejeita a Promise retornando a string 'Erro de conexão' 32 | reject('Erro de conexão') 33 | } 34 | 35 | // Envia a request. 36 | req.send() 37 | }) 38 | } -------------------------------------------------------------------------------- /06/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | YouTube 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 | 14 |
15 |
16 |

Faça sua busca...

17 |
18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /06/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brizental/reprograma-javascript/546e37dfb5508033382b34b899b654ecea3f4ba3/06/loading.gif -------------------------------------------------------------------------------- /06/main.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | font-family: 'Roboto', sans-serif; } 4 | 5 | #container { 6 | width: 500px; 7 | padding: 30px; 8 | margin: 80px auto; 9 | min-height: 80vh; 10 | box-shadow: 0px 0px 48px 0px rgba(0, 0, 0, 0.31); } 11 | 12 | form input { 13 | width: 100%; 14 | padding: 10px 15px; 15 | border: 1px solid #e0e0e0; } 16 | 17 | #results { 18 | margin-top: 30px; } 19 | #results > p { 20 | text-align: center; 21 | color: grey; } 22 | #results a { 23 | color: black; 24 | text-decoration: none; 25 | display: block; 26 | padding: 20px; 27 | margin-bottom: 20px; 28 | border: 1px solid #e0e0e0; 29 | transition: box-shadow 200ms ease-in; } 30 | #results a:hover { 31 | box-shadow: 0px 0px 7px 0px rgba(0, 0, 0, 0.3); } 32 | #results a h1 { 33 | margin-bottom: 15px; 34 | font-size: 16px; 35 | margin: 0; } 36 | #results a p { 37 | margin-bottom: 0; } 38 | 39 | /*# sourceMappingURL=main.css.map */ 40 | -------------------------------------------------------------------------------- /06/main.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "mappings": "AAAA,CAAE;EACA,UAAU,EAAE,UAAU;EACtB,WAAW,EAAE,oBAAoB;;AAGnC,UAAW;EACT,KAAK,EAAE,KAAK;EACZ,OAAO,EAAE,IAAI;EACb,MAAM,EAAE,SAAS;EACjB,UAAU,EAAE,IAAI;EAChB,UAAU,EAAE,oCAAiC;;AAI7C,UAAM;EACJ,KAAK,EAAE,IAAI;EACX,OAAO,EAAE,SAAS;EAClB,MAAM,EAAE,iBAAiB;;AAI7B,QAAS;EACP,UAAU,EAAE,IAAI;EAEhB,YAAM;IACJ,UAAU,EAAE,MAAM;IAClB,KAAK,EAAE,IAAI;EAGb,UAAE;IACA,KAAK,EAAC,KAAK;IACX,eAAe,EAAE,IAAI;IACrB,OAAO,EAAE,KAAK;IACd,OAAO,EAAE,IAAI;IACb,aAAa,EAAE,IAAI;IACnB,MAAM,EAAE,iBAAiB;IACzB,UAAU,EAAE,wBAAwB;IAEpC,gBAAQ;MACN,UAAU,EAAE,kCAA+B;IAG7C,aAAG;MACD,aAAa,EAAE,IAAI;MACnB,SAAS,EAAE,IAAI;MACf,MAAM,EAAE,CAAC;IAGX,YAAE;MACA,aAAa,EAAE,CAAC", 4 | "sources": ["main.scss"], 5 | "names": [], 6 | "file": "main.css" 7 | } -------------------------------------------------------------------------------- /06/main.js: -------------------------------------------------------------------------------- 1 | const form = document.querySelector("form") 2 | const input = document.querySelector("input") 3 | const results = document.getElementById("results") 4 | 5 | // let promiseHasResolved = false 6 | // input.addEventListener("click", function() { 7 | // if (promiseHasResolved) { 8 | // input.value = "" 9 | // promiseHasResolved = false 10 | // } 11 | // }) 12 | 13 | form.addEventListener("submit", function(event){ 14 | event.preventDefault() 15 | }) 16 | 17 | input.addEventListener("keyup", function(event) { 18 | // event.preventDefault() 19 | results.innerHTML = 'Gif de carregamento' 20 | getData(`https://www.googleapis.com/youtube/v3/search?part=snippet&type=vidasdfasdfasdfaeo&q=${input.value}&key=AIzaSyA2oJySYmGJxeYqkLAMqPBQNOK6ZOH30Q8`).then( 21 | function(response) { 22 | // promiseHasResolved = true 23 | const jsonResponse = JSON.parse(response) 24 | results.innerHTML = '' 25 | if (jsonResponse.items.length === 0) { 26 | results.innerHTML = '

Nenhum resultado encontrado

' 27 | } else { 28 | for (const video of jsonResponse.items) { 29 | results.innerHTML = results.innerHTML + ` 30 | 31 | Prévia do vídeo 32 |

${video.snippet.title}

33 |

${video.snippet.description}

34 |
35 | ` 36 | } 37 | } 38 | }, 39 | function(error) { 40 | // promiseHasResolved = true 41 | results.innerHTML = `

${error}

` 42 | }) 43 | }) -------------------------------------------------------------------------------- /06/main.scss: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | font-family: 'Roboto', sans-serif; 4 | } 5 | 6 | #container { 7 | width: 500px; 8 | padding: 30px; 9 | margin: 80px auto; 10 | min-height: 80vh; 11 | box-shadow: 0px 0px 48px 0px rgba(0,0,0,0.31); 12 | } 13 | 14 | form { 15 | input { 16 | width: 100%; 17 | padding: 10px 15px; 18 | border: 1px solid #e0e0e0; 19 | } 20 | } 21 | 22 | #results { 23 | margin-top: 30px; 24 | 25 | & > p { 26 | text-align: center; 27 | color: grey; 28 | } 29 | 30 | a { 31 | color:black; 32 | text-decoration: none; 33 | display: block; 34 | padding: 20px; 35 | margin-bottom: 20px; 36 | border: 1px solid #e0e0e0; 37 | transition: box-shadow 200ms ease-in; 38 | 39 | &:hover { 40 | box-shadow: 0px 0px 7px 0px rgba(0,0,0,0.3); 41 | } 42 | 43 | h1 { 44 | margin-bottom: 15px; 45 | font-size: 16px; 46 | margin: 0; 47 | } 48 | 49 | p { 50 | margin-bottom: 0; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /07/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Escolhas 8 | 9 | 10 | 11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | 37 | 38 | -------------------------------------------------------------------------------- /07/main.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | #container { 6 | width: 960px; 7 | margin: 30px auto; 8 | display: flex; 9 | align-items: center; 10 | } 11 | 12 | .column { 13 | width: 25%; 14 | height: 100%; 15 | margin-right: 100px; 16 | display: flex; 17 | flex-direction: column; 18 | justify-content: center; 19 | } 20 | 21 | .column div { 22 | width: 100%; 23 | height: 10px; 24 | margin-bottom: 20px; 25 | } 26 | 27 | .column div:nth-child(odd) { 28 | margin-top: 70px; 29 | } -------------------------------------------------------------------------------- /07/main.js: -------------------------------------------------------------------------------- 1 | const columns = document.querySelectorAll(".column") 2 | for (const column of columns) { 3 | const colors = column.children 4 | for (let i = 0; i < colors.length; i++) { 5 | colors[i].addEventListener("click", function(event) { 6 | const bg = event.target.style.backgroundColor 7 | const colorParent = event.target.parentElement 8 | const colorParentSibling = colorParent.nextElementSibling 9 | if (colorParentSibling !== null) { 10 | const colorsFromSibling = colorParentSibling.children 11 | colorsFromSibling[Math.floor(i/2)].style.backgroundColor = bg 12 | } 13 | }) 14 | } 15 | } -------------------------------------------------------------------------------- /08/README.md: -------------------------------------------------------------------------------- 1 | > http://reprograma-quiz.surge.sh/ -------------------------------------------------------------------------------- /08/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Quiz 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 |
15 | 19 |
20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /08/main.css: -------------------------------------------------------------------------------- 1 | *{box-sizing:border-box;font-family:'Montserrat', sans-serif;font-weight:200}body{background:linear-gradient(to bottom, #4b015e 0%, #2a013f 100%);height:100vh;overflow:hidden;margin:0;padding:0}button{text-transform:uppercase;background-color:white;color:#260138;font-size:12px;text-align:center;border:none;padding:10px 30px;cursor:pointer}#container{display:flex;align-items:center;justify-content:center;flex-direction:column;min-height:100vh}#container button{box-shadow:0px 0px 17px -5px rgba(0,0,0,0.75);transition:box-shadow 200ms ease-in-out;border-radius:18px}#container button:hover{box-shadow:0px 0px 17px -1px rgba(0,0,0,0.75)}#container ul{color:white;list-style-type:none;padding:20px;width:100vw}#container ul li{margin-bottom:20px}#container ul li .right{color:green}#container ul li .wrong{color:red}#overlay{position:absolute;top:100vh;height:100vh;width:100%;transition:top 400ms ease-in-out;background:linear-gradient(to bottom, #2a013f 0%, #4b015e 100%);background-color:black}#overlay #header{display:flex;justify-content:space-between;color:white;padding:20px 30px}#overlay #header #close{font-size:20px;cursor:pointer}#overlay #questions{transition:left 200ms ease-in-out;position:absolute;left:0;height:100vh;width:100vw}#overlay #questions .question{position:absolute;display:flex;justify-content:center;flex-direction:column;height:70%;width:100%;padding:0 30px}#overlay #questions .question p{color:white;text-align:center}#overlay #questions .question .answers{width:60vw;margin:30px auto}#overlay #questions .question .answers button{width:100%;display:block}#overlay #questions .question .answers button:first-of-type{border-bottom:1px solid #260138} 2 | /*# sourceMappingURL=main.css.map */ 3 | -------------------------------------------------------------------------------- /08/main.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "mappings": "AAAA,CAAE,CACA,UAAU,CAAE,UAAU,CACtB,WAAW,CAAE,wBAAwB,CACrC,WAAW,CAAE,GAAG,CAGlB,IAAK,CACH,UAAU,CAAE,oDAAmE,CAC/E,MAAM,CAAE,KAAK,CACb,QAAQ,CAAE,MAAM,CAChB,MAAM,CAAE,CAAC,CACT,OAAO,CAAE,CAAC,CAGZ,MAAO,CACL,cAAc,CAAE,SAAS,CACzB,gBAAgB,CAAE,KAAK,CACvB,KAAK,CAAE,OAAO,CACd,SAAS,CAAE,IAAI,CACf,UAAU,CAAE,MAAM,CAClB,MAAM,CAAE,IAAI,CACZ,OAAO,CAAE,SAAS,CAClB,MAAM,CAAE,OAAO,CAGjB,UAAW,CACT,OAAO,CAAE,IAAI,CACb,WAAW,CAAE,MAAM,CACnB,eAAe,CAAE,MAAM,CACvB,cAAc,CAAE,MAAM,CACtB,UAAU,CAAE,KAAK,CAEjB,iBAAO,CACL,UAAU,CAAE,kCAAkC,CAC9C,UAAU,CAAE,4BAA4B,CACxC,aAAa,CAAE,IAAI,CACnB,uBAAQ,CACN,UAAU,CAAE,kCAAkC,CAIlD,aAAG,CACD,KAAK,CAAE,KAAK,CACZ,eAAe,CAAE,IAAI,CACrB,OAAO,CAAE,IAAI,CACb,KAAK,CAAE,KAAK,CAEZ,gBAAG,CACD,aAAa,CAAE,IAAI,CAEnB,uBAAO,CACL,KAAK,CAAE,KAAK,CAGd,uBAAO,CACL,KAAK,CAAE,GAAG,CAMlB,QAAS,CACP,QAAQ,CAAE,QAAQ,CAClB,GAAG,CAAE,KAAK,CACV,MAAM,CAAE,KAAK,CACb,KAAK,CAAE,IAAI,CACX,UAAU,CAAE,qBAAqB,CACjC,UAAU,CAAE,oDAAmE,CAC/E,gBAAgB,CAAE,KAAK,CAEvB,gBAAQ,CACN,OAAO,CAAE,IAAI,CACb,eAAe,CAAE,aAAa,CAC9B,KAAK,CAAE,KAAK,CACZ,OAAO,CAAE,SAAS,CAElB,uBAAO,CACL,SAAS,CAAE,IAAI,CACf,MAAM,CAAE,OAAO,CAInB,mBAAW,CACT,UAAU,CAAE,sBAAsB,CAClC,QAAQ,CAAE,QAAQ,CAClB,IAAI,CAAE,CAAC,CACP,MAAM,CAAE,KAAK,CACb,KAAK,CAAE,KAAK,CAEZ,6BAAU,CACR,QAAQ,CAAE,QAAQ,CAClB,OAAO,CAAE,IAAI,CACb,eAAe,CAAE,MAAM,CACvB,cAAc,CAAE,MAAM,CACtB,MAAM,CAAE,GAAG,CACX,KAAK,CAAE,IAAI,CACX,OAAO,CAAE,MAAM,CAEf,+BAAE,CACA,KAAK,CAAE,KAAK,CACZ,UAAU,CAAE,MAAM,CAGpB,sCAAS,CACP,KAAK,CAAE,IAAI,CACX,MAAM,CAAE,SAAS,CAEjB,6CAAO,CACL,KAAK,CAAE,IAAI,CACX,OAAO,CAAE,KAAK,CAEd,2DAAgB,CACd,aAAa,CAAE,iBAAiB", 4 | "sources": ["main.scss"], 5 | "names": [], 6 | "file": "main.css" 7 | } -------------------------------------------------------------------------------- /08/main.js: -------------------------------------------------------------------------------- 1 | /* Objeto com as perguntas */ 2 | let questions = [ 3 | { 4 | text: "Lorem ipsum dolor sit amet?", 5 | answer: true 6 | }, 7 | { 8 | text: "Consectetur adipiscing elit?", 9 | answer: false 10 | }, 11 | { 12 | text: "Pellentesque sit amet mi egestas?", 13 | answer: true 14 | } 15 | ] 16 | 17 | /* Elementos necessarios para o quiz funcionar */ 18 | const questionsAll = document.getElementById("questions") 19 | const closeButton = document.getElementById("close") 20 | const startButton = document.querySelector("#container button") 21 | const overlay = document.getElementById("overlay") 22 | const timer = document.getElementById("timer") 23 | const container = document.getElementById("container") 24 | 25 | /* Abrir e fechar o quiz */ 26 | let interval = undefined 27 | startButton.addEventListener("click", openQuiz) 28 | closeButton.addEventListener("click", closeQuiz) 29 | 30 | function openQuiz() { 31 | overlay.style.top = "0vh" 32 | interval = startTimer(timer) 33 | } 34 | 35 | function closeQuiz() { 36 | setTimeout(function () { 37 | questionsAll.style.left = "0vw" 38 | }, 500) 39 | overlay.style.top = "100vh" 40 | clearInterval(interval) 41 | } 42 | 43 | /* Timer */ 44 | function startTimer(element) { 45 | element.innerHTML = "00:00" 46 | const now = Date.now() 47 | return setInterval(() => { 48 | const updatedNow = Date.now() 49 | const diffDate = new Date(updatedNow - now) 50 | // let minutes 51 | // if (diffDate.getMinutes() < 10) { 52 | // minutes = "0" + diffDate.getMinutes() 53 | // } else { 54 | // minutes = diffDate.getMinutes() 55 | // } 56 | // let seconds 57 | // if (diffDate.getSeconds() < 10) { 58 | // seconds = "0" + diffDate.getSeconds() 59 | // } else { 60 | // seconds = diffDate.getSeconds() 61 | // } 62 | const minutes = diffDate.getMinutes() < 10 63 | ? "0" + diffDate.getMinutes() : diffDate.getMinutes() 64 | const seconds = diffDate.getSeconds() < 10 65 | ? "0" + diffDate.getSeconds() : diffDate.getSeconds() 66 | element.innerHTML = minutes + ":" + seconds 67 | }, 1000) 68 | } 69 | 70 | /* Crio o HTML das perguntas */ 71 | for (let i = 0; i < questions.length; i++) { 72 | const questionDiv = document.createElement("div") 73 | questionDiv.classList.add("question") 74 | questionDiv.style.left = 100 * i + "vw" 75 | 76 | const questionP = document.createElement("p") 77 | questionP.textContent = questions[i].text 78 | 79 | const answersDiv = document.createElement("div") 80 | answersDiv.classList.add("answers") 81 | 82 | const trueButton = document.createElement("button") 83 | trueButton.textContent = "VERDADEIRO" 84 | const falseButton = document.createElement("button") 85 | falseButton.textContent = "FALSO" 86 | 87 | questionDiv.appendChild(questionP) 88 | 89 | answersDiv.appendChild(trueButton) 90 | answersDiv.appendChild(falseButton) 91 | 92 | questionDiv.appendChild(answersDiv) 93 | 94 | questionsAll.appendChild(questionDiv) 95 | 96 | trueButton.addEventListener("click", function() { 97 | questions[i].userAnswer = true 98 | nextQuizStep(i) 99 | }) 100 | 101 | falseButton.addEventListener("click", function() { 102 | questions[i].userAnswer = false 103 | nextQuizStep(i) 104 | }) 105 | } 106 | 107 | function nextQuizStep(index) { 108 | if (index < questions.length - 1) { 109 | questionsAll.style.left = `calc(${questionsAll.offsetLeft}px - 100vw)` 110 | } else { 111 | let answeredQuestions = '' 112 | for (const question of questions) { 113 | answeredQuestions += ` 114 |
  • 115 | ${question.text}
    116 | 117 | ${question.userAnswer === true ? "VERDADEIRO" : "FALSO"} 118 | 119 |
  • 120 | ` 121 | } 122 | 123 | container.innerHTML = `` 124 | 125 | const tryAgainButton = document.createElement("button") 126 | tryAgainButton.textContent = "Tente novamente" 127 | tryAgainButton.addEventListener("click", openQuiz) 128 | container.appendChild(tryAgainButton) 129 | 130 | closeQuiz() 131 | } 132 | } -------------------------------------------------------------------------------- /08/main.scss: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | font-family: 'Montserrat', sans-serif; 4 | font-weight: 200; 5 | } 6 | 7 | body { 8 | background: linear-gradient(to bottom, rgba(75,1,94,1) 0%,rgba(42,1,63,1) 100%); 9 | height: 100vh; 10 | overflow: hidden; 11 | margin: 0; 12 | padding: 0; 13 | } 14 | 15 | button { 16 | text-transform: uppercase; 17 | background-color: white; 18 | color: #260138; 19 | font-size: 12px; 20 | text-align: center; 21 | border: none; 22 | padding: 10px 30px; 23 | cursor: pointer; 24 | } 25 | 26 | #container { 27 | display: flex; 28 | align-items: center; 29 | justify-content: center; 30 | flex-direction: column; 31 | min-height: 100vh; 32 | 33 | button { 34 | box-shadow: 0px 0px 17px -5px rgba(0,0,0,0.75); 35 | transition: box-shadow 200ms ease-in-out; 36 | border-radius: 18px; 37 | &:hover { 38 | box-shadow: 0px 0px 17px -1px rgba(0,0,0,0.75); 39 | } 40 | } 41 | 42 | ul { 43 | color: white; 44 | list-style-type: none; 45 | padding: 20px; 46 | width: 100vw; 47 | 48 | li { 49 | margin-bottom: 20px; 50 | 51 | .right { 52 | color: green; 53 | } 54 | 55 | .wrong { 56 | color: red; 57 | } 58 | } 59 | } 60 | } 61 | 62 | #overlay { 63 | position: absolute; 64 | top: 100vh; 65 | height: 100vh; 66 | width: 100%; 67 | transition: top 400ms ease-in-out; 68 | background: linear-gradient(to bottom, rgba(42,1,63,1) 0%,rgba(75,1,94,1) 100%); 69 | background-color: black; 70 | 71 | #header { 72 | display: flex; 73 | justify-content: space-between; 74 | color: white; 75 | padding: 20px 30px; 76 | 77 | #close { 78 | font-size: 20px; 79 | cursor: pointer; 80 | } 81 | } 82 | 83 | #questions { 84 | transition: left 200ms ease-in-out; 85 | position: absolute; 86 | left: 0; 87 | height: 100vh; 88 | width: 100vw; 89 | 90 | .question { 91 | position: absolute; 92 | display: flex; 93 | justify-content: center; 94 | flex-direction: column; 95 | height: 70%; 96 | width: 100%; 97 | padding: 0 30px; 98 | 99 | p { 100 | color: white; 101 | text-align: center; 102 | } 103 | 104 | .answers { 105 | width: 60vw; 106 | margin: 30px auto; 107 | 108 | button { 109 | width: 100%; 110 | display: block; 111 | 112 | &:first-of-type { 113 | border-bottom: 1px solid #260138; 114 | } 115 | } 116 | } 117 | } 118 | } 119 | } --------------------------------------------------------------------------------