PushState do histórico do JavaScript

Resumo : neste tutorial, você aprenderá como usar o pushState()método de histórico JavaScript.

Introdução ao pushState()método de histórico JavaScript

O history.pushState()método permite adicionar uma entrada à pilha do histórico de sessões do navegador da web .

Aqui está a sintaxe do pushState()método:

history.pushState(state, title, [,url])Linguagem de código:  CSS  ( css )

O pushState()método aceita três parâmetros:

1) estado

O stateé um objeto serializável. Quando você navega para um novo estado, um popstateevento é acionado. E o popstateevento possui uma statepropriedade que faz referência ao stateobjeto da entrada do histórico.

2) título

A maioria dos navegadores atualmente possui esta propriedade de título. Se quiser alterar o título do documento, você pode usar a documen.titlepropriedade.

Na prática, você passa uma string vazia para o titleparâmetro.

3) URL

O opcional urlpermite definir o URL da nova entrada do histórico. A URL deve ter a mesma origem da URL atual ou o método lançará uma exceção.

Quando você define o novo arquivo url, o navegador da web não carrega o arquivo url. O urlpadrão é o URL atual se você não especificá-lo.

pushState()Exemplo de histórico de JavaScript

Faremos um aplicativo simples que mostra três abas: React, Vue e Angular.

Quando você clica em uma guia, o conteúdo da guia selecionada é exibido. também atualizará o URL usando o histórico. pushState()método:

Se você copiar o URL com a hashtag e carregá-lo do navegador da web, o aplicativo carregará o conteúdo correspondente associado a esse URL.

Clique no link a seguir para ver a demonstração do aplicativo.

Faça a página index.html

O seguinte define a index.htmlpágina:

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>JavaScript History API: pushState Demo</title>
		<link rel="stylesheet" href="css/style.css" />
	</head>

	<body>
		<div class="container">
			<div class="tabs">
				<ul>
					<li class="active" id="tab1">React</li>
					<li id="tab2">Vue</li>
					<li id="tab3">Angular</li>
				</ul>
				<div class="content">
					A JavaScript library for building user interfaces
				</div>
			</div>
		</div>

		<script src="js/app.js"></script>
	</body>
</html>
Linguagem de código:  HTML, XML  ( xml )

E você pode encontrar o style.cssarquivo aqui.

No app.jsarquivo:

Primeiro, selecione as guias e os elementos de conteúdo usando o querySelector()método:

const tabs = document.querySelector(".tabs");
const content = document.querySelector(".tabs > .content");Linguagem de código:  JavaScript  ( javascript )

Segundo, defina um objeto de mapa que associe o hash da URL a cada ID de guia:

const hashes = new Map([
    ["#react", "tab1"],
    ["#vue", "tab2"],
    ["#angular", "tab3"],
]);Linguagem de código:  JavaScript  ( javascript )

Terceiro, defina outro mapa chamado data para mapear o ID da guia com um objeto. O objeto tem duas propriedades: urle content.

const data = new Map([
    [
        "tab1",
        {
            url: "index.html#react",
            content:
                "React is a JavaScript library for building user interfaces.",
        },
    ],
    [
        "tab2",
        {
            url: "index.html#vue",
            content: "Vue is the Progressive JavaScript Framework.",
        },
    ],
    [
        "tab3",
        {
            url: "index.html#angular",
            content:
                "Angular is a platform for building mobile and desktop web applications.",
        },
    ],
]);Linguagem de código:  JavaScript  ( javascript )

Quarto, quando cada aba (ou elemento li) é clicada, o clickevento ocorre. Para torná-lo mais eficiente, usaremos a delegação de eventos .

Então, em vez de tratar o clickevento em cada aba, vamos tratar o clickevento no pai de cada aba:

tabs.addEventListener("click", function (event) {
    if (!event.target.id) return;
    update(event.target.id);
});Linguagem de código:  JavaScript  ( javascript )

A ifinstrução garante que o manipulador de eventos atualize apenas o conteúdo e o URL se o clickevento ocorrer em cada guia individual. Não fará nada quando você clicar na área de conteúdo da guia.

Dentro do manipulador de eventos, chamamos a update()função e passamos o ID da guia para ela.

Quinto, o seguinte define a update()função:

const update = (tabId) => {
    // remove the active class of the previously selected tab
    const currentTab = tabs.querySelector(".active");

    if (currentTab.id != tabId) {
        currentTab.classList.remove("active");
    }
    // add active class to the selected tab
    const selectedTab = document.getElementById(tabId);
    selectedTab.classList.add("active");

    const entry = data.get(tabId);

    if (entry) {
        // update the URL
        history.pushState(null, "", entry.url);
        // change the content
        content.innerHTML = entry.content;
    }
};Linguagem de código:  JavaScript  ( javascript )

A update()função remove a .activeclasse da guia atual e define a mesma classe CSS para a guia atualmente selecionada.

Ele também obtém o URL e o conteúdo dos dados com base no ID da guia. Para atualizar a URL, ele usa o history.pushState()método.

O aplicativo deve estar funcionando conforme esperado, com apenas um problema.

Se você copiar o URL:

https://tutorials.acervolima.com/sample/webapis/history/index.html#angularLinguagem de código:  JavaScript  ( javascript )

… e cole-o na nova janela do navegador, o aplicativo mostrará a Reactguia em vez da Angularguia.

Para corrigir isso, obtemos o hash da URL usando o locationobjeto e chamamos a update()função quando a página é carregada.

(() => {
    // get tab id from the hash
    const tabId = hashes.get(window.location.hash);
    // update the tab
    if (tabId) update(tabId);
})();Linguagem de código:  JavaScript  ( javascript )

A seguir mostra o app.jsarquivo completo:

const tabs = document.querySelector(".tabs");
const content = document.querySelector(".tabs > .content");

// store the relationship between hash & tab id
const hashes = new Map([
    ["#react", "tab1"],
    ["#vue", "tab2"],
    ["#angular", "tab3"],
]);

// store the relationship between tab id and contents
const data = new Map([
    [
        "tab1",
        {
            url: "index.html#react",
            content:
                "React is a JavaScript library for building user interfaces.",
        },
    ],
    [
        "tab2",
        {
            url: "index.html#vue",
            content: "Vue is the Progressive JavaScript Framework.",
        },
    ],
    [
        "tab3",
        {
            url: "index.html#angular",
            content:
                "Angular is a platform for building mobile and desktop web applications.",
        },
    ],
]);

tabs.addEventListener("click", function (event) {
    if (!event.target.id) return;
    update(event.target.id);
});

const update = (tabId) => {
    // remove the active class of the previously selected tab
    const currentTab = tabs.querySelector(".active");

    if (currentTab.id != tabId) {
        currentTab.classList.remove("active");
    }
    // add active class to the selected tab
    const selectedTab = document.getElementById(tabId);
    selectedTab.classList.add("active");

    const entry = data.get(tabId);

    if (entry) {
        // update the URL
        history.pushState(null, "", entry.url);
        // change the content
        content.innerHTML = entry.content;
    }
};

(() => {
    // get tab id from the hash
    const tabId = hashes.get(window.location.hash);
    // update the tab
    if (tabId) update(tabId);
})();Linguagem de código:  JavaScript  ( javascript )

Resumo

  • Use o history.pushState()método para adicionar uma entrada à pilha do histórico de sessões do navegador da web.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *