roger-melo-treinamentos / curso-de-js-roger-melo

Repositório de informações do CJRM
491 stars 170 forks source link

Duvida - Correção dos exercícios da aula 02 da etapa 06 - Aula 01-01 #4898

Closed MarioFilho1 closed 2 years ago

MarioFilho1 commented 2 years ago

Etapa da aula

7

Nome da aula

Correção dos exercícios da aula 02 da etapa 06 - Aula 01-01

Link da aula

https://app.nutror.com/v3/curso/a977a43d31cedcb6e7d064649ddd6c5436155aaf/curso-de-javascript-roger-melo/aula/943413

Descreva a dúvida

@Roger-Melo

Olá, Roger,

Estou com uma dúvida na lógica desse exercício em relação a primeira opção que foi implementada para evitar a repetição de parágrafos que eram inseridos ao digitar um novo caractere.

inputUsername.addEventListener('keyup', event => {
  const inputValue = event.target.value
  const usernameRegex = /^[a-zA-Z]{6,}$/

  const p = document.querySelector('p')
  p.setAttribute('data-feedback', 'username-feedback')

  const feedbackParagraph = document.querySelector('[data-feedback="username-feedback"]')

  if(feedbackParagraph) {
      feedbackParagraph.remove()
   }

  if(usernameRegex.test(inputValue)) {
     p.textContent = 'O valor deve conter no mínimo 6 caracteres, com apenas letras maiúsculas e/ou minúsculas'
     event.target.insertAdjacentElement('afterend', p)
     return
    }
})

1º É criado um elemento 'p' sempre que clicamos em algum caractere 2° Foi atribuído uma classe data-feedback ao elemento 'p' 3° É atribuído a referência da classe para a const feedbackParagraph 4º É variável feedbackParagraph é testada no if para verificar se existe a classe, caso exista ela é removida

Pelo que percebi, sempre que o elemento 'p' é criado, o atributo data é atribuído a ele, assim, sempre que for realizado o teste no if, haverá a remoção do elemento 'p', Então, como é que o elemento 'p' foi inserido a primeira vez, já que ele sempre é removido?

Roger-Melo commented 2 years ago

Olá @MarioFilho1!

Pode postar todo o código dos arquivos js, html e css? Assim posso ajudar com mais precisão =)

Estou longe do pc agora mas quando chegar em casa lhe respondo =)

MarioFilho1 commented 2 years ago

Ai está o código completo até o momento que tive a dúvida.


<!DOCTYPE html>
<html lang="pt-br">
<head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Roboto:300,300italic,700,700italic">
  <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.css">
  <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/milligram/1.3.0/milligram.css">
  <link rel="stylesheet" href="./style.css">
  <title>Exercício 18</title>
</head>
<body>
  <div class="container">
    <h1>Exercício 18</h1>

    <form>
      <fieldset>
        <label for="username">Nome de usuário</label>
        <input
          type="text"
          placeholder="Cadastre seu nome de usuário"
          id="username"
          autofocus
          autocomplete ="off"
        >

        <button class="button">Enviar</button>
      </fieldset>
    </form>
  </div>

  <script src="./app.js"></script>
</body>
</html>

```html

```css

.container {
  max-width: 80rem;
  padding-top: 7.5rem;
}

.username-help-feedback {
  margin-bottom: 2.5rem;
  color: darkorange;
}

.username-success-feedback {
  margin-bottom: 2.5rem;
  color: green;
}

.submit-help-feedback {
  margin-bottom: 2.5rem;
  color: red;
}

.submit-success-feedback {
  margin-bottom: 2.5rem;
  color: green;
}
const usernameInput = document.querySelector('#username')

inputUsername.addEventListener('keyup', event => {
    const inputValue = event.target.value
    const usernameRegex = /^[a-zA-Z]{6,}$/

    const p = document.querySelector('p')
    p.setAttribute('data-feedback', 'username-feedback')

    const feedbackParagraph = document.querySelector('[data-feedback="username-feedback"]')

    if(feedbackParagraph) {
        feedbackParagraph.remove()
    }

    if(usernameRegex.test(inputValue)) {
        p.textContent = 'O valor deve conter no mínimo 6 caracteres, com apenas letras maiúsculas e/ou minúsculas'
        event.target.insertAdjacentElement('afterend', p)
        return
    }
      p.textContent = 'Username Valido :)'
      event.target.insertAdjacentElement('afterend', p)
})

Só pra lembrar, depois de dar esse exemplo de evitar a repetição de inserção do parágrafo, vc mostrou outra forma mais simples, que era apenas retirando de dentro do bloco de código a instrução que criava o elemento 'p'. Mas minha dúvida é no primeiro exemplo com relatado acima.

MarioFilho1 commented 2 years ago

Olá Roger,

A dúvida foi sanada :). Assisti novamente a aula. Eu não tinha prestado atenção direito. Agora entendi que no teste abaixo, só será verdadeiro se o elemento for inserido na tela.



 const feedbackParagraph = document.querySelector('[data-feedback="username-feedback"]')

 if(feedbackParagraph) {
        feedbackParagraph.remove()
    }
`´`
Roger-Melo commented 2 years ago

Olá @MarioFilho1!

Legal que sanou a dúvida. Deixa só eu fazer uma observação, pra não pecar pela falta.

1º É criado um elemento 'p' sempre que clicamos em algum caractere

p não está sendo criado.

const p = document.querySelector('p')

A linha acima apenas seleciona um <p> que já existe no DOM.

Lembra que querySelector é um método que busca e seleciona um elemento no DOM?

Se vc precisa criar um parágrafo de forma dinâmica no JS, é necessário substituir querySelector pelo createElement:

const p = document.createElement('p')
console.log(p) // <p></p>

2° Foi atribuído uma classe data-feedback ao elemento 'p'

Não.

Com o código abaixo o setAttribute não irá saber que o p deve ter um atributo class que recebe o nome da classe:

p.setAttribute('data-feedback', 'username-feedback')

O setAttribute precisa receber 2 argumentos:

  1. Nome do atributo (class, data-*, src, etc).
  2. Valor do atributo.

Se vc quer setar um atributo class que recebe "abc", é necessário especificar isso no setAttribute:

p.setAttribute('class', 'abc') // <p class="abc"></p>

3° É atribuído a referência da classe para a const feedbackParagraph

Vc está falando dessa linha?

const feedbackParagraph = document.querySelector('[data-feedback="username-feedback"]')

Ela não atribui referência de classe. Essa linha está buscando no DOM um elemento que contém o atributo data-feedback com o valor "username-feedback". Ou seja, data-feedback="username-feedback".


4º É variável feedbackParagraph é testada no if para verificar se existe a classe, caso exista ela é removida

Não é classe.

const feedbackParagraph = document.querySelector('[data-feedback="username-feedback"]')

if (feedbackParagraph) {
  feedbackParagraph.remove()
}

feedbackParagraph pode armazenar 2 valores:

  1. null, caso o elemento com o atributo data-feedback="username-feedback" não seja encontrado no DOM;
  2. A referência do elemento (objeto) no DOM.

Se feedbackParagraph armazena null, o if não vai ser executado pq null é um valor falsy.

Se feedbackParagraph armazena o objeto, o if vai ser executado pq objeto é um valor truthy.

Se o if é executado, o parágrafo é removido do DOM.

Está ficando mais claro?

MarioFilho1 commented 2 years ago

Olá Roger, No primeiro tópico foi falta de atenção ao dizer que jsconst p = document.querySelector('p')criava um elemento, colei a instrução errada. Obrigado pelos demais esclarecimentos, ainda estava com uma noção errada de algumas coisas. Abriu mais a minha mente :)

Roger-Melo commented 2 years ago

Massa @MarioFilho1.

DOM é um assunto denso e fundamental para a carreira de um Dev JS. No futuro, ao trabalhar com React, por exemplo, essa base em DOM irá fazer vc entender como o React abstrai manipulação de DOM.

Por isso, recomendo que revise essa etapa quantas vezes for necessário, até que fique mais natural para vc. Combinado?

Vou fechar a issue mas no que precisar, é só abrir uma nova =)

MarioFilho1 commented 2 years ago

Combinado! Obrigado!