Vamos começar já ajustando nosso projeto para suportar os módulos ESM. Crie uma pasta “js” para melhor organizar os arquivos javascript e também altere o tipo da tag script no arquivo index.html para “module”:
<!-- ... -->
<title>Projeto Prático Guiado 1</title>
<link rel="stylesheet" href="style.css">
<script src="js/index.js" type="module" defer></script>
</head>
<body>
<!-- ... -->
Agora vamos começar. Mova o arquivo “index.js” para a pasta “js” criada e crie nela o arquivo “calculate.js”. Vamos mover para ele a função “calculate” do arquivo principal e fazer as devidas adaptações no código, nesse caso obtendo o input de resultado dentro da função:
export default function calculate() {
const resultInput = document.querySelector("#result")
resultInput.value = "ERROR"
resultInput.classList.add("error")
const result = eval(input.value)
resultInput.value = result
resultInput.classList.remove("error")
}
Outra parte da aplicação que podemos separar são os eventos de copiar para área de transferência e mudar o tema. Vamos começar pelo botão de copiar. Crie um arquivo “copyToClipboard.js” e exporte a função, fazendo as devidas adaptações:
export default function copyToClipboard(ev) {
const button = ev.currentTarget
if (button.innerText === "Copy") {
button.innerText = "Copied!"
button.classList.add("success")
navigator.clipboard.writeText(document.querySelector("#result").value)
} else {
button.innerText = "Copy"
button.classList.remove("success")
}
}
Agora vamos para a função de mudança de tema. Crie o arquivo “themeSwitcher.js” e mova para ele a função de mudar o tema entre dark e light. Também será preciso obter os elementos main e root dentro da função:
export default function switchTheme() {
const main = document.querySelector("main")
const root = document.querySelector(":root")
if (main.dataset.theme === "dark") {
root.style.setProperty("--bg-color", "#f1f5f9")
root.style.setProperty("--border-color", "#aaa")
root.style.setProperty("--font-color", "#212529")
root.style.setProperty("--primary-color", "#26834a")
main.dataset.theme = "light"
} else {
root.style.setProperty("--bg-color", "#212529")
root.style.setProperty("--border-color", "#666")
root.style.setProperty("--font-color", "#f1f5f9")
root.style.setProperty("--primary-color", "#4dff91")
main.dataset.theme = "dark"
}
}
Poderíamos parar por aqui, mas ainda há mais que podemos modularizar nessa aplicação. Vamos separar as funções ligadas aos eventos de digitação e clique nos botões da calculadora. Para isso, crie o arquivo “keyHandlers.js”. Nele precisaremos adaptar o código para conter as variáveis necessárias para o seu funcionamento, como o “input” e as “allowedKeys”. Também vamos precisar importar nossa função calculate() para o arquivo:
import calculate from "./calculate.js"
const input = document.querySelector('#input')
export function handleButtonPress(ev) {
const value = ev.currentTarget.dataset.value
input.value += value
}
export function handleClear(ev) {
input.value = ""
input.focus()
}
export function handleTyping(ev) {
ev.preventDefault()
const allowedKeys = ["(", ")", "/", "*", "-", "+", "9", "8", "7", "6", "5", "4", "3", "2", "1", "0", ".", "%", " "]
if (allowedKeys.includes(ev.key)) {
input.value += ev.key
return
}
if (ev.key === "Backspace") {
input.value = input.value.slice(0, -1)
}
if (ev.key === "Enter") {
calculate()
}
}
Para finalizar, vamos fazer os ajustes necessários no arquivo “index.js”, importando os módulos e então vamos testar a aplicação para ver se tudo continua funcionando como antes:
import calculate from "./calculate.js"
import copyToClipboard from "./copyToClipboard.js"
import { handleButtonPress, handleClear, handleTyping } from "./keyHandlers.js"
import switchTheme from "./switchTheme.js"
document.querySelectorAll(".charKey").forEach(function (charKeyBtn) {
charKeyBtn.addEventListener("click", handleButtonPress)
})
document.querySelector("#clear").addEventListener("click", handleClear)
document.querySelector("#input").addEventListener("keydown", handleTyping)
document.querySelector("#equal").addEventListener("click", calculate)
document.querySelector("#copyToClipboard").addEventListener("click", copyToClipboard)
document.querySelector("#themeSwitcher").addEventListener("click", switchTheme)