aboutsummaryrefslogtreecommitdiff
path: root/files/pt-br/learn/javascript/building_blocks/build_your_own_function/index.html
blob: 80f5faf9b3f83e27d821f9f92a548c58e22d8305 (plain)
1
2
3
4
5
6
7
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
---
title: Construa sua própria função
slug: Learn/JavaScript/Building_blocks/Build_your_own_function
translation_of: Learn/JavaScript/Building_blocks/Build_your_own_function
original_slug: Aprender/JavaScript/Elementos_construtivos/Build_your_own_function
---
<div>{{LearnSidebar}}</div>

<div>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Functions","Learn/JavaScript/Building_blocks/Return_values", "Learn/JavaScript/Building_blocks")}}</div>

<p class="summary">Com a maior parte da teoria essencial tratada no artigo anterior, este artigo fornece experiência prática. Aqui você terá algumas práticas construindo sua própria função personalizada. Ao longo do caminho, também explicaremos alguns detalhes úteis sobre como lidar com funções.</p>

<table class="learn-box standard-table">
 <tbody>
  <tr>
   <th scope="row">Pré-requisitos:</th>
   <td>Alfabetização básica em informática, um entendimento básico de HTML e CSS, <a href="/en-US/docs/Learn/JavaScript/First_steps">Primeiros passos do JavaScript</a>, <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Funções — blocos reutilizáveis de código</a>.</td>
  </tr>
  <tr>
   <th scope="row">Objetiva:</th>
   <td>Para fornecer alguma prática na criação de uma função personalizada e explicar alguns detalhes associados mais úteis.</td>
  </tr>
 </tbody>
</table>

<h2 id="Aprendizagem_ativa_vamos_construir_uma_função">Aprendizagem ativa: vamos construir uma função</h2>

<p>A função personalizada que vamos construir será chamada  <code>displayMessage().</code> Ele exibirá uma caixa de mensagem personalizada em uma página da Web e atuará como um substituto personalizado para a função de <a href="/en-US/docs/Web/API/Window/alert">alert()</a> interna do navegador. Já vimos isso antes, mas vamos apenas refrescar nossas memórias. Digite o seguinte no console JavaScript do seu navegador, em qualquer página de sua preferência:</p>

<pre class="brush: js notranslate">alert('This is a message');</pre>

<p>A função <code>alert</code> leva um único argumento — a string exibida na caixa de alerta. Tente variar a string para mudar a mensagem.</p>

<p>A função <code>alert</code> é limitada: você pode alterar a mensagem, mas não pode variar com facilidade nada, como cor, ícone ou qualquer outra coisa. Nós vamos construir um que se mostrará mais divertido.</p>

<div class="note">
<p><strong>Nota</strong>: Este exemplo deve funcionar bem em todos os navegadores modernos, mas o estilo pode parecer um pouco engraçado em navegadores um pouco mais antigos. Recomendamos que você faça esse exercício em um navegador moderno como o Firefox, o Opera ou o Chrome.</p>
</div>

<h2 id="A_função_básica">A função básica</h2>

<p>Para começar, vamos montar uma função básica.</p>

<div class="note">
<p><strong>Note</strong>: Para convenções de nomenclatura de função, você deve seguir as mesmas regras das <a href="/en-US/Learn/JavaScript/First_steps/Variables#An_aside_on_variable_naming_rules">convenções de nomenclatura de variáveis</a>. Algo bom é como você pode diferenciá-los — os nomes das funções aparecem com parênteses depois deles e as variáveis não.</p>
</div>

<ol>
 <li>Comece acessando o arquivo <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/functions/function-start.html">function-start.html</a> e fazendo uma cópia local. Você verá que o HTML é simples — o corpo contém apenas um único botão. Também fornecemos algumas CSS básicas para estilizar a caixa de mensagem personalizada e um elemento {{htmlelement("script")}} vazio para colocar nosso JavaScript.</li>
 <li>Em seguida, adicione o seguinte dentro do elemento <code>&lt;script&gt;</code> :
  <pre class="brush: js notranslate">function displayMessage() {

}</pre>
  Começamos com a palavra-chave <code>function</code>, o que significa que estamos definindo uma função. Isto é seguido pelo nome que queremos dar à nossa função, um par de parênteses e um conjunto de chaves. Quaisquer parâmetros que queremos dar à nossa função vão dentro dos parênteses, e o código que é executado quando chamamos a função vai dentro das chaves.</li>
 <li>Por fim, adicione o seguinte código dentro das chaves:
  <pre class="brush: js notranslate">var html = document.querySelector('html');

var panel = document.createElement('div');
panel.setAttribute('class', 'msgBox');
html.appendChild(panel);

var msg = document.createElement('p');
msg.textContent = 'This is a message box';
panel.appendChild(msg);

var closeBtn = document.createElement('button');
closeBtn.textContent = 'x';
panel.appendChild(closeBtn);

closeBtn.onclick = function() {
  panel.parentNode.removeChild(panel);
}</pre>
 </li>
</ol>

<p>Isso é um monte de código para passar, então vamos guiá-lo pouco a pouco.</p>

<p>A primeira linha usa uma função da API do DOM chamada {{domxref("document.querySelector()")}} para selecionar o elemento {{htmlelement("html")}} e armazenar uma referência a ele em uma variável chamada <code>html</code>, para que possamos fazer coisas com ela mais tarde:</p>

<pre class="brush: js notranslate">var html = document.querySelector('html');</pre>

<p>A próxima seção usa outra função da API do DOM chamada {{domxref("Document.createElement()")}} para criar um elemento {{htmlelement("div")}} elemento e armazenar uma referência a ele em uma variável chamada <code>panel</code>. Este elemento será o recipiente externo da nossa caixa de mensagens.</p>

<p>Em seguida, usamos outra função da API do DOM chamada {{domxref("Element.setAttribute()")}} para setar o atributo <code>class</code> atributo no nosso painel com um valor de <code>msgBox</code>. Isso é para facilitar o estilo do elemento — se você olhar para o CSS na página, verá que estamos usando um seletor de classe <code>.msgBox</code> para estilizar a caixa de mensagem e seu conteúdo.</p>

<p>Finalmente, chamamos uma função DOM chamada {{domxref("Node.appendChild()")}} na variável <code>html</code> vque armazenamos anteriormente, que nidifica um elemento dentro do outro como um filho dele. Nós especificamos o painel <code>&lt;div&gt;</code> como o filho que queremos acrescentar dentro do elemento <code>&lt;html&gt;</code> Precisamos fazer isso porque o elemento que criamos não aparecerá na página sozinho — precisamos especificar onde colocá-lo.</p>

<pre class="brush: js notranslate">var panel = document.createElement('div');
panel.setAttribute('class', 'msgBox');
html.appendChild(panel);</pre>

<p>As próximas duas seções fazem uso das mesmas funções <code>createElement()</code><code>appendChild()</code> que já vimos para criar dois novos elementos — um {{htmlelement("p")}} e um {{htmlelement("button")}} — e inseri-los na página como filhos do painel <code>&lt;div&gt;</code>. Nós usamos a sua propriedade {{domxref("Node.textContent")}} — que representa o conteúdo de texto de um elemento — para inserir uma mensagem dentro do parágrafo e um 'x' dentro do botão. Este botão será o que precisa ser clicado / ativado quando o usuário quiser fechar a caixa de mensagem.</p>

<pre class="brush: js notranslate">var msg = document.createElement('p');
msg.textContent = 'This is a message box';
panel.appendChild(msg);

var closeBtn = document.createElement('button');
closeBtn.textContent = 'x';
panel.appendChild(closeBtn);</pre>

<p>Finalmente, usamos um manipulador eventos {{domxref("GlobalEventHandlers.onclick")}} para fazer com que, quando o botão é clicado, algum código seja executado para excluir todo o painel da página — para fechar a caixa de mensagem.</p>

<p>Resumidamente, o manipulador <code>onclick</code> é uma propriedade disponível no botão (ou, na verdade, qualquer elemento na página) que pode ser definida para uma função para especificar qual código será executado quando o botão for clicado. Você aprenderá muito mais sobre isso em nosso artigo de eventos posteriores. Estamos tornando o manipulador <code>onclick</code> igual a uma função anônima, que contém o código a ser executado quando o botão é clicado. A linha dentro da função usa a função da API do DOM {{domxref("Node.removeChild()")}} para especificar que queremos remover um elemento filho específico do elemento HTML — nesse caso, o painel <code>&lt;div&gt;</code>.</p>

<pre class="brush: js notranslate">closeBtn.onclick = function() {
  panel.parentNode.removeChild(panel);
}</pre>

<p>Basicamente, todo esse bloco de código está gerando um bloco de HTML semelhante a isso e inserindo-o na página:</p>

<pre class="brush: html notranslate">&lt;div class="msgBox"&gt;
  &lt;p&gt;This is a message box&lt;/p&gt;
  &lt;button&gt;x&lt;/button&gt;
&lt;/div&gt;</pre>

<p>Isso foi um monte de código para trabalhar — não se preocupe muito se você não se lembra exatamente como tudo funciona agora! A parte principal que queremos focar aqui é a estrutura e uso da função, mas queremos mostrar algo interessante para este exemplo.</p>

<h2 id="Chamando_a_função">Chamando a função</h2>

<p>Você tem sua própria definição de função escrita em seu elemento  <code>&lt;script&gt;</code>, mas não fará nada do jeito que está.</p>

<ol>
 <li>Tente incluir a seguinte linha abaixo da sua função para chamá-lo:
  <pre class="brush: js notranslate">displayMessage();</pre>
  Esta linha chama a função, fazendo com que ela seja executada imediatamente. Quando você salvar seu código e recarregá-lo no navegador, verá a pequena caixa de mensagem aparecer imediatamente, apenas uma vez. Nós só estamos chamando uma vez, afinal.</li>
 <li>
  <p>Agora abra suas ferramentas de desenvolvedor do navegador na página de exemplo, vá para o console JavaScript e digite a linha novamente, você verá que ela aparece novamente! Então isso é divertido — agora temos uma função reutilizável que podemos chamar a qualquer momento que quisermos.</p>

  <p>Mas provavelmente queremos que apareça em resposta a ações do usuário e do sistema. Em um aplicativo real, essa caixa de mensagem provavelmente seria chamada em resposta a novos dados sendo disponibilizados, ou um erro ocorreria, ou o usuário tentando excluir seu perfil ("você tem certeza disso?") Ou o usuário adicionando um novo contato e a operação completando com sucesso ... etc.</p>

  <p>Nesta demonstração, faremos com que a caixa de mensagem apareça quando o usuário clicar no botão.</p>
 </li>
 <li>Exclua a linha anterior que você adicionou.</li>
 <li>Em seguida, vamos selecionar o botão e armazenar uma referência a ele em uma variável. Adicione a seguinte linha ao seu código, acima da definição da função:
  <pre class="brush: js notranslate">var btn = document.querySelector('button');</pre>
 </li>
 <li>Por fim, adicione a seguinte linha abaixo da anterior:
  <pre class="brush: js notranslate">btn.onclick = displayMessage;</pre>
  De maneira semelhante à nossa linha  <code>closeBtn.onclick...</code> dentro da função, aqui estamos chamando algum código em resposta a um botão sendo clicado. Mas, neste caso, em vez de chamar uma função anônima contendo algum código, estamos chamando nosso nome de função diretamente.</li>
 <li>Tente salvar e atualizar a página — agora você verá a caixa de mensagem quando clicar no botão.</li>
</ol>

<p>Você pode estar se perguntando por que não incluímos os parênteses após o nome da função. Isso ocorre porque não queremos chamar a função imediatamente — somente depois que o botão foi clicado. Se você tentar mudar a linha para</p>

<pre class="brush: js notranslate">btn.onclick = displayMessage();</pre>

<p>e salvar e recarregar, você verá que a caixa de mensagem aparece sem que o botão seja clicado! Os parênteses neste contexto são às vezes chamados de "operador de invocação de função". Você só os usa quando deseja executar a função imediatamente no escopo atual. No mesmo sentido, o código dentro da função anônima não é executado imediatamente, pois está dentro do escopo da função.</p>

<p>Se você tentou o último experimento, certifique-se de desfazer a última alteração antes de continuar.</p>

<h2 id="Melhorando_a_função_com_parâmetros">Melhorando a função com parâmetros</h2>

<p>Tal como está, a função ainda não é muito útil — nós não queremos apenas mostrar a mesma mensagem padrão todas as vezes. Vamos melhorar nossa função adicionando alguns parâmetros, permitindo-nos chamá-lo com algumas opções diferentes.</p>

<ol>
 <li>Primeiro de tudo, atualize a primeira linha da função:
  <pre class="brush: js notranslate">function displayMessage() {</pre>
  para isso:</li>
 <li>
  <pre class="brush: js notranslate">function displayMessage(msgText, msgType) {</pre>
  Agora, quando chamamos a função, podemos fornecer dois valores de variáveis dentro dos parênteses para especificar a mensagem a ser exibida na caixa de mensagem e o tipo de mensagem que ela é.</li>
 <li>Para utilizar o primeiro parâmetro, atualize a seguinte linha dentro da sua função:
  <pre class="brush: js notranslate">msg.textContent = 'This is a message box';</pre>
  to

  <pre class="brush: js notranslate">msg.textContent = msgText;</pre>
 </li>
 <li>Por último, mas não menos importante, você precisa atualizar sua chamada de função para incluir um texto de mensagem atualizado. Altere a seguinte linha:
  <pre class="brush: js notranslate">btn.onclick = displayMessage;</pre>
  para este bloco:

  <pre class="brush: js notranslate">btn.onclick = function() {
  displayMessage('Woo, this is a different message!');
};</pre>
  Se quisermos especificar parâmetros dentro de parênteses para a função que estamos chamando, então não podemos chamá-la diretamente — precisamos colocá-lo dentro de uma função anônima para que não fique no escopo imediato e, portanto, não seja chamado imediatamente. Agora ele não será chamado até que o botão seja clicado.</li>
 <li>Recarregue e tente o código novamente e você verá que ele ainda funciona muito bem, exceto que agora você também pode variar a mensagem dentro do parâmetro para obter mensagens diferentes exibidas na caixa!</li>
</ol>

<h3 id="Um_parâmetro_mais_complexo">Um parâmetro mais complexo</h3>

<p>Para o próximo parâmetro. Este vai envolver um pouco mais de trabalho — vamos configurá-lo para que, dependendo do parâmetro <code>msgType</code>, a função mostre um ícone diferente e uma cor de fundo diferente.</p>

<ol>
 <li>Primeiro de tudo, baixe os ícones necessários para este exercício (<a href="https://raw.githubusercontent.com/mdn/learning-area/master/javascript/building-blocks/functions/icons/warning.png">aviso</a> e <a href="https://raw.githubusercontent.com/mdn/learning-area/master/javascript/building-blocks/functions/icons/chat.png">batepapo</a>) do GitHub. Salve-os em uma nova pasta chamada  <code>icons</code> no mesmo local que seu arquivo HTML.

  <div class="note"><strong>Nota</strong>: Os icones <a href="https://www.iconfinder.com/icons/1031466/alarm_alert_error_warning_icon">aviso</a> e <a href="https://www.iconfinder.com/icons/1031441/chat_message_text_icon">batepapo</a> são encontrado em iconfinder.com, e desenhados por <a href="https://www.iconfinder.com/nazarr">Nazarrudin Ansyari</a>. Obrigado!</div>
 </li>
 <li>Em seguida, encontre o CSS dentro do seu arquivo HTML. Faremos algumas alterações para abrir caminho para os ícones. Primeiro, atualize a largura do <code>.msgBox</code> de:
  <pre class="brush: css notranslate">width: 200px;</pre>
  para:</li>
 <li>
  <pre class="brush: css notranslate">width: 242px;</pre>
 </li>
 <li>Em seguida, adicione as seguintes linhas dentro da regra <code>.msgBox p { ... }</code>:
  <pre class="brush: css notranslate">padding-left: 82px;
background-position: 25px center;
background-repeat: no-repeat;</pre>
 </li>
 <li>Agora precisamos adicionar código à nossa função <code>displayMessage()</code> para manipular a exibição dos ícones. Adicione o seguinte bloco logo acima da chave de fechamento (<code>}</code>) da sua função:
  <pre class="brush: js notranslate">if (msgType === 'warning') {
  msg.style.backgroundImage = 'url(icons/warning.png)';
  panel.style.backgroundColor = 'red';
} else if (msgType === 'chat') {
  msg.style.backgroundImage = 'url(icons/chat.png)';
  panel.style.backgroundColor = 'aqua';
} else {
  msg.style.paddingLeft = '20px';
}</pre>
  Aqui, se o parâmetro <code>msgType</code> estiver definido como <code>'warning'</code>, o ícone de aviso será exibido e a cor de fundo do painel será definida como vermelha. Se estiver definido para <code>'chat'</code>, o ícone de bate-papo é exibido e a cor de fundo do painel é definida como azul aqua. Se o parâmetro <code>msgType</code> não estiver definido (ou para algo diferente), então a parte <code>else { ... }</code> do código entra em jogo, e o parágrafo é simplesmente fornecido padding padrão e nenhum ícone, sem conjunto de cores do painel de fundo também. Isso fornece um estado padrão se nenhum parâmetro <code>msgType</code> for fornecido, significando que é um parâmetro opcional!</li>
 <li>Vamos testar nossa função atualizada, tente atualizar a chamada <code>displayMessage()</code> a partir disso:
  <pre class="brush: js notranslate">displayMessage('Woo, this is a different message!');</pre>
  para um destes:</li>
 <li>
  <pre class="brush: js notranslate">displayMessage('Your inbox is almost full — delete some mails', 'warning');
displayMessage('Brian: Hi there, how are you today?','chat');</pre>
  Você pode ver como a nossa pequena função (agora nem tanto) está se tornando útil.</li>
</ol>

<div class="note">
<p><strong>Nota</strong>: Se você tiver problemas para fazer o exemplo funcionar, sinta-se à vontade para verificar seu código na <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/functions/function-stage-4.html">versão finalizada no GitHub</a> (<a href="http://mdn.github.io/learning-area/javascript/building-blocks/functions/function-stage-4.html">veja-a também em execução</a>), ou peça nos ajuda.</p>
</div>

<h2 id="Conclusão">Conclusão</h2>

<p>Parabéns por chegar ao final! Este artigo levou você ao longo de todo o processo de criação de uma função prática personalizada, que com um pouco mais de trabalho poderia ser transplantada em um projeto real. No próximo artigo, vamos encerrar as funções explicando outro conceito relacionado essencial — valores de retorno.</p>

<ul>
</ul>

<p>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Functions","Learn/JavaScript/Building_blocks/Return_values", "Learn/JavaScript/Building_blocks")}}</p>

<h2 id="In_this_module">In this module</h2>

<ul>
 <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals">Making decisions in your code — conditionals</a></li>
 <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">Looping code</a></li>
 <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Functions — reusable blocks of code</a></li>
 <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Build your own function</a></li>
 <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">Function return values</a></li>
 <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events">Introduction to events</a></li>
 <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Image_gallery">Image gallery</a></li>
</ul>