4 minuto(s) de leitura

Este projeto exibe a localização estimada baseada no IP.
A API por ipgeolocation.

Após inserir um endereço IPv4, a página deve retornar o local estimado deste IP, graças a API.

Imagens 📷

IPlocation1

IPlocation2

Passos 📔

Crie uma pasta para armazenar todos os arquivos.

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Rastrear IP</title>
    <link rel="stylesheet" href="style.css">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://unpkg.com/boxicons@2.0.9/css/boxicons.min.css">
</head>
    <body>
        <div class="wrapper">
            <header><i class="bx bx-left-arrow-alt"></i>Rastrear IP</header>
            <section class="input-part">
                <p class="info-txt"></p>
                <input type="text" placeholder="Digite um IP" spellcheck="false" required>
                <div class="separator"></div>
                <button>Obter o IP do dispositivo</button>
            </section>
            <section class="ip-part">
                <img src="_" alt="Bandeira do país">
                <div class="location">
                    <div class="min-detail">
                        <i class='bx bxs-city'></i>
                        <span class="city">_, _</span>
                    </div>
                    <div class="other-locations">
                        <span class="continent">_, _</span>
                        <span class="country">_, _</span>
                        <span class="region">_, _</span>
                    </div>
                </div>
                <div class="map">
                    <i class='bx bx-map-alt'></i>
                    <span><a href="_" target="_blank"></a></span>
                </div>
                <div class="ip-address">
                    <i class='bx bxs-devices'></i>
                    <span>_</span>
                </div>
                <div class="bottom-details">
                    <div class="column feels">
                        <i class="bx bx-map"></i>
                        <div class="details">
                            <div class="lat-long">
                                <span>_, _</span>
                            </div>
                            <p>Latitude e longitude</p>
                        </div>
                    </div>
                    <div class="column security">
                        <i class='bx bx-check-shield' ></i>
                        <div class="details">
                            <span>_</span>
                            <p>VPN</p>
                        </div>
                    </div>
                    <div class="column currency">
                        <i class='bx bx-coin' ></i>
                        <div class="details">
                            <span>_, _</span>
                            <p>Moeda</p>
                        </div>
                    </div>
                    <div class="column timezone">
                        <i class='bx bx-time' ></i>
                        <div class="details">
                            <span>_:_:_</span>
                            <p>Horário</p>
                        </div>
                    </div>
                </div>
            </section>
        </div>

        <script src="script.js"></script>

    </body>
</html>

style.css

@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');

:root {
    --cor-do-site: #742e06;
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: 'Poppins', sans-serif;
}
body {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    background: var(--cor-do-site);
}
.wrapper {
    width: 600px;
    border-radius: 7px;
    background: #fff;
}
.wrapper header {
    color: var(--cor-do-site);
    font-size: 21px;
    font-weight: 500;
    padding: 16px 15px;
    display: flex;
    align-items: center;
    border-bottom: 1px solid #bfbfbf;
}
header i {
    cursor: pointer;
    font-size: 30px;
    margin-right: 8px;
}
.wrapper.active header {
    font-size: 30px;
    margin-left: 5px;
}
.wrapper .input-part {
    margin: 20px 25px 30px;
}
.wrapper.active .input-part {
    display: none;
}
.input-part .info-txt {
    display: none;
    font-size: 17px;
    text-align: center;
    padding: 12px 10px;
    border-radius: 7px;
    margin-bottom: 15px;
}
.info-txt.error {
    display: block;
    color: #721c24;
    background: #f8d7da;
    border: 1px solid #f5c6cb;
}
.info-txt.pending {
    display: block;
    color: #0c5460;
    background: #d1ecf1;
    border: 1px solid #bee5eb;
}
.input-part :where(input, button) {
    width: 100%;
    height: 55px;
    border: none;
    outline: none;
    font-size: 18px;
    border-radius: 7px;
}
.input-part input {
    text-align: center;
    border: 1px solid #bfbfbf;
}
.input-part input:is(:focus, :valid) {
    border: 2px solid var(--cor-do-site);
}
.input-part .separator {
    height: 1px;
    width: 100%;
    margin: 25px 0;
    background: #ccc;
    display: flex;
    align-items: center;
    justify-content: center;
}
.separator::before {
    content: "ou";
    color: #ccc;
    font-size: 19px;
    padding: 0 15px;
    background: #fff;
}
.input-part button {
    color: #fff;
    cursor: pointer;
    background: var(--cor-do-site);
}

.wrapper .ip-part {
    margin: 30px 0 0;
    display: none;
    align-items: center;
    justify-content: center;
    flex-direction: column;
}
.wrapper.active .ip-part {
    display: flex;
}
.ip-part img {
    max-width: 300px;
}
.ip-part .location {
    justify-content: center;
    font-size: 45px;
    font-weight: 500;
}
.ip-part .location .min-detail {
    display: flex;
    align-items: center;
}
.min-detail i {
    font-size: 45px;
    margin-right: 5px;
}
.ip-part .location .other-locations {
    display: flex;
    flex-direction: column;
    font-size: 28px;
    margin: 10px 5px 0 0;
}
.ip-part .location .city {
    font-weight: 600;
}
.map {
    display: flex;
    align-items: center;
    margin: 10px 5px 0 0;
}
.map i {
    font-size: 22px;
    margin-right: 5px;
}
.map span {
    font-size: 22px;
    font-weight: 600;
}
.map span a {
    text-decoration: underline;
}
.ip-part .ip-address {
    display: flex;
    align-items: center;
    font-size: 21px;
    margin: 10px 5px 30px 0;
}
.ip-address i {
    font-size: 22px;
    margin-right: 5px;
}
#mapid {
    height: 300px;
}
.ip-part .bottom-details {
    width: 100%;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    border-top: 1px solid #bfbfbf;
    justify-content: space-between;
}
.bottom-details .column {
    width: 100%;
    display: flex;
    flex: 1 0 50%; /* quebrar flex após certo tamanho */
    padding: 15px 0;
    align-items: center;
    justify-content: center;
}
.column i {
    color: var(--cor-do-site);
    font-size: 40px;
}
.column.security {
    border-left: 1px solid #bfbfbf;
}
.column.currency {
    border-left: 1px solid #bfbfbf;
    border-top: 1px solid #bfbfbf;
}
.column.timezone {
    border-left: 1px solid #bfbfbf;
    border-top: 1px solid #bfbfbf;
}
.details, .security span {
    font-size: 18px;
    font-weight: 500;
    margin-top: -3px;
}
.details .temp .deg {
    margin: 0;
    font-size: 17px;
    padding: 0 2px 0 1px;
}
.details p {
    font-size: 14px;
    margin-top: -6px;
}

script.js

const wrapper = document.querySelector(".wrapper"),
inputPart = wrapper.querySelector(".input-part"),
infoTxt = inputPart.querySelector(".info-txt"),
inputField = inputPart.querySelector("input"),
localIpBtn = inputPart.querySelector("button"),
wIcon = wrapper.querySelector(".ip-part img"),
map = wrapper.querySelector(".map span a"),
arrowBack = wrapper.querySelector("header i");

const apiKey = 'API_KEY_CODE';
let api;

inputField.addEventListener("keyup", e => {
    // se pressionar o botão Enter e o valor não for nulo
    if (e.key == "Enter" && inputField.value != "") {
        requestApi(inputField.value);
    }
});

localIpBtn.addEventListener("click", () => {
    api = `https://ipgeolocation.abstractapi.com/v1/?api_key=${apiKey}&ip_address=`;
    fetchData();
});

function requestApi(ip) {
    api = `https://ipgeolocation.abstractapi.com/v1/?api_key=${apiKey}&ip_address=${ip}`;
    fetchData();
}

function fetchData() {
    infoTxt.innerText = "Obtendo detalhes do IP...";
    infoTxt.classList.add("pending");
    // coleta os dados da API e manda à função weatherDetails
    fetch(api).then(
        response => response.json().then(
            result => ipDetails(result)
        )
    );
}

function ipDetails(info) {
    infoTxt.classList.replace("pending", "error");
    if(info.cod == "404") {
        infoTxt.innerText = `${inputField.value} ocorreu um erro.`;
    } else {
        // coletando as informações do Json
        const {flag} = info;
        const {city, continent, continent_code, country, country_code, region, region_iso_code, ip_address, latitude, longitude, security, currency, timezone} = info;

        // passando as informações para um elemento HTML
        wIcon.src = flag.png;
        wrapper.querySelector(".city").innerText = `${city}, ${region_iso_code}`;
        wrapper.querySelector(".continent").innerText = `${continent}, ${continent_code}`;
        wrapper.querySelector(".country").innerText = `${country}, ${country_code}`;
        wrapper.querySelector(".region").innerText = `${region}, ${region_iso_code}`;
        map.href = `https://www.google.com/maps/search/${latitude},${longitude}/@2,12.9978113,17z?hl=pt-br`;
        wrapper.querySelector(".map span a").innerText = "Map Locaton";
        wrapper.querySelector(".ip-address span").innerText = ip_address;
        wrapper.querySelector(".lat-long span").innerText = `${latitude}, ${longitude}`;
        wrapper.querySelector(".security span").innerText = security.is_vpn;
        wrapper.querySelector(".currency span").innerText = `${currency.currency_code}, ${currency.currency_name}`;
        wrapper.querySelector(".timezone span").innerText = timezone.current_time;

        infoTxt.classList.remove("pending", "error");
        wrapper.classList.add("active");
    }
}

arrowBack.addEventListener("click", () => {
    wrapper.classList.remove("active");
});

Lembre-se de criar uma conta no site, obter o seu código e substituir em API_KEY_CODE no arquivo script.js.

Agora é só abrir o index.html no navegador.

Ferramentas usadas 🛠

  • HTML and CSS
  • JavaScript
  • API

Deixe um comentário