Išnagrinėkite CSS vaizdo perėjimus, sutelkdami dėmesį į būsenos išsaugojimą ir animacijos atkūrimą. Sužinokite, kaip sukurti sklandžią vartotojo patirtį net naršant pirmyn ir atgal.
CSS vaizdo perėjimų būsenos išsaugojimas: animacijos būsenos atkūrimas
CSS vaizdo perėjimai (angl. View Transitions) yra galinga nauja funkcija, leidžianti kūrėjams sukurti sklandžius ir vizualiai patrauklius perėjimus tarp skirtingų interneto aplikacijos būsenų. Nors pradinis įgyvendinimas buvo sutelktas į pagrindinius perėjimus, esminis aspektas kuriant iš tiesų nušlifuotą vartotojo patirtį yra būsenos išsaugojimo ir animacijos atkūrimo valdymas, ypač naršant pirmyn ir atgal tarp puslapių ar sekcijų.
Būtinybės išsaugoti būseną supratimas
Įsivaizduokite vartotoją, naršantį nuotraukų galerijoje. Kiekvienas paspaudimas perkelia prie kito paveikslėlio su gražia animacija. Tačiau, jei vartotojas paspaudžia naršyklės mygtuką „atgal“, jis tikisi, kad animacija apsisuks ir grąžins jį į ankstesnio paveikslėlio būseną. Be būsenos išsaugojimo, naršyklė gali tiesiog grįžti į ankstesnį puslapį be jokio perėjimo, o tai sukelia staigų ir nenuoseklų potyrį.
Būsenos išsaugojimas užtikrina, kad aplikacija prisimena ankstesnę vartotojo sąsajos būseną ir gali sklandžiai grįžti į ją. Tai ypač svarbu vieno puslapio aplikacijoms (angl. Single Page Applications, SPA), kuriose naršymas dažnai apima DOM manipuliavimą be pilno puslapio perkrovimo.
Pagrindiniai vaizdo perėjimai: apžvalga
Prieš pradedant gilintis į būsenos išsaugojimą, greitai prisiminkime CSS vaizdo perėjimų pagrindus. Pagrindinis mechanizmas apima būseną keičiančio kodo apgaubimą document.startViewTransition()
:
document.startViewTransition(() => {
// Atnaujinti DOM į naują būseną
updateTheDOM();
});
Tada naršyklė automatiškai užfiksuoja seną ir naują atitinkamų DOM elementų būsenas ir animuoja perėjimą tarp jų naudodama CSS. Animaciją galite pritaikyti naudodami CSS savybes, tokias kaip transition-behavior: view-transition;
.
Iššūkis: animacijos būsenos išsaugojimas grįžtant atgal
Didžiausias iššūkis kyla, kai vartotojas inicijuoja „atgal“ naršymo įvykį, paprastai paspausdamas naršyklės mygtuką „atgal“. Naršyklės numatytasis elgesys dažnai yra atkurti puslapį iš podėlio (cache), efektyviai apeinant „View Transition“ API. Tai sukelia minėtą staigų grįžimą į ankstesnę būseną.
Animacijos būsenos atkūrimo sprendimai
Galima pritaikyti kelias strategijas šiam iššūkiui spręsti ir užtikrinti sklandų animacijos būsenos atkūrimą.
1. History API ir popstate
įvykio naudojimas
History API suteikia smulkiagrūdę naršyklės istorijos dėklo (angl. history stack) kontrolę. Įkeliant naujas būsenas į istorijos dėklą su history.pushState()
ir klausantis popstate
įvykio, galite perimti grįžimo atgal navigaciją ir paleisti atvirkštinį vaizdo perėjimą.
Pavyzdys:
// Funkcija, skirta pereiti į naują būseną
function navigateTo(newState) {
document.startViewTransition(() => {
updateTheDOM(newState);
history.pushState(newState, null, newState.url);
});
}
// Klausytis popstate įvykio
window.addEventListener('popstate', (event) => {
const state = event.state;
if (state) {
document.startViewTransition(() => {
updateTheDOM(state); // Grįžti į ankstesnę būseną
});
}
});
Šiame pavyzdyje navigateTo()
atnaujina DOM ir įkelia naują būseną į istorijos dėklą. Tada popstate
įvykio klausytojas perima grįžimo atgal navigaciją ir paleidžia kitą vaizdo perėjimą, kad grįžtų į ankstesnę būseną. Svarbiausia čia yra išsaugoti pakankamai informacijos state
objekte, perduotame per `history.pushState`, kad galėtumėte atkurti ankstesnę DOM būseną updateTheDOM
funkcijoje. Tai dažnai apima atitinkamų duomenų, naudojamų ankstesniam vaizdui atvaizduoti, išsaugojimą.
2. Page Visibility API panaudojimas
Page Visibility API leidžia nustatyti, kada puslapis tampa matomas ar paslėptas. Kai vartotojas išeina iš puslapio, jis tampa paslėptas. Kai jis grįžta, puslapis vėl tampa matomas. Galite naudoti šį API, kad paleistumėte atvirkštinį vaizdo perėjimą, kai puslapis tampa matomas po to, kai buvo paslėptas.
Pavyzdys:
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'visible') {
document.startViewTransition(() => {
// Grįžti į ankstesnę būseną remiantis podėlyje esančiais duomenimis
revertToPreviousState();
});
}
});
Šis metodas remiasi ankstesnės DOM būsenos išsaugojimu podėlyje (caching) prieš puslapiui tampant paslėptam. Funkcija revertToPreviousState()
tada naudotų šiuos podėlyje esančius duomenis, kad atkurtų ankstesnį vaizdą ir inicijuotų atvirkštinį perėjimą. Tai gali būti paprasčiau įgyvendinti nei History API metodą, tačiau reikalauja kruopštaus podėlio duomenų valdymo.
3. History API ir Session Storage derinimas
Sudėtingesniems scenarijams gali tekti derinti History API su sesijos saugykla (session storage), kad išsaugotumėte su animacija susijusius duomenis. Sesijos saugykla leidžia saugoti duomenis, kurie išlieka naršant po puslapius tame pačiame naršyklės skirtuke. Galite saugoti animacijos būseną (pvz., dabartinį kadrą ar eigą) sesijos saugykloje ir gauti ją, kai vartotojas grįžta į puslapį.
Pavyzdys:
// Prieš išeinant iš puslapio:
sessionStorage.setItem('animationState', JSON.stringify(currentAnimationState));
// Puslapio įkėlimo arba popstate įvykio metu:
const animationState = JSON.parse(sessionStorage.getItem('animationState'));
if (animationState) {
document.startViewTransition(() => {
// Atkurti animacijos būseną ir paleisti atvirkštinį perėjimą
restoreAnimationState(animationState);
});
}
Šis pavyzdys saugo currentAnimationState
(kuris gali apimti informaciją apie animacijos eigą, dabartinį kadrą ar bet kokius kitus svarbius duomenis) sesijos saugykloje prieš išeinant iš puslapio. Kai puslapis įkeliamas arba suveikia popstate
įvykis, animacijos būsena gaunama iš sesijos saugyklos ir naudojama animacijai atkurti į ankstesnę būseną.
4. Karkaso ar bibliotekos naudojimas
Daugelis šiuolaikinių JavaScript karkasų ir bibliotekų (pvz., React, Vue.js, Angular) teikia integruotus mechanizmus būsenos valdymui ir navigacijai. Šie karkasai dažnai abstrahuoja History API sudėtingumą ir siūlo aukštesnio lygio API būsenos ir perėjimų valdymui. Naudodami karkasą, apsvarstykite galimybę pasinaudoti jo integruotomis funkcijomis būsenos išsaugojimui ir animacijos atkūrimui.
Pavyzdžiui, React aplinkoje galite naudoti būsenos valdymo biblioteką, tokią kaip Redux ar Zustand, kad saugotumėte aplikacijos būseną ir ją išlaikytumėte naršant po puslapius. Tada galite naudoti React Router navigacijai valdyti ir vaizdo perėjimams paleisti remiantis aplikacijos būsena.
Geriausios būsenos išsaugojimo įgyvendinimo praktikos
- Sumažinkite saugomų duomenų kiekį: Saugokite tik esminius duomenis, reikalingus ankstesnei būsenai atkurti. Didelių duomenų kiekių saugojimas gali paveikti našumą.
- Naudokite efektyvią duomenų serializaciją: Saugodami duomenis sesijos saugykloje, naudokite efektyvius serializacijos metodus, pvz.,
JSON.stringify()
, kad sumažintumėte saugyklos dydį. - Apdorokite kraštutinius atvejus: Apsvarstykite kraštutinius atvejus, pavyzdžiui, kai vartotojas pirmą kartą apsilanko puslapyje (t. y. nėra ankstesnės būsenos).
- Kruopščiai testuokite: Išbandykite būsenos išsaugojimo ir animacijos atkūrimo mechanizmą skirtingose naršyklėse ir įrenginiuose.
- Atsižvelkite į prieinamumą: Užtikrinkite, kad perėjimai būtų prieinami vartotojams su negalia. Suteikite alternatyvius naršymo būdus, jei perėjimai trikdo.
Kodo pavyzdžiai: išsamesnė analizė
Išplėskime ankstesnius pavyzdžius pateikdami detalesnes kodo ištraukas.
1 pavyzdys: History API su detalia būsena
// Pradinė būsena
let currentState = {
page: 'home',
data: {},
scrollPosition: 0 // Pavyzdys: išsaugoti slinkties poziciją
};
function updateTheDOM(newState) {
// Atnaujinti DOM remiantis newState (pakeiskite savo tikrąja logika)
console.log('Updating DOM to:', newState);
document.getElementById('content').innerHTML = `Navigated to: ${newState.page}
`;
window.scrollTo(0, newState.scrollPosition); // Atkurti slinkties poziciją
}
function navigateTo(page) {
document.startViewTransition(() => {
// 1. Atnaujinti DOM
currentState = {
page: page,
data: {},
scrollPosition: 0 // Nustatyti slinktį iš naujo arba ją išsaugoti
};
updateTheDOM(currentState);
// 2. Įkelti naują būseną į istoriją
history.pushState(currentState, null, '#' + page); // Naudoti grotažymę (hash) paprastam maršrutizavimui
});
}
window.addEventListener('popstate', (event) => {
document.startViewTransition(() => {
// 1. Grįžti į ankstesnę būseną
const state = event.state;
if (state) {
currentState = state;
updateTheDOM(currentState);
} else {
// Apdoroti pradinį puslapio įkėlimą (būsenos dar nėra)
navigateTo('home'); // Arba kitą numatytąją būseną
}
});
});
// Pradinis įkėlimas: pakeisti pradinę būseną, kad išvengtumėte problemų su mygtuku „atgal“
history.replaceState(currentState, null, '#home');
// Naudojimo pavyzdys:
document.getElementById('link-about').addEventListener('click', (e) => {
e.preventDefault();
navigateTo('about');
});
document.getElementById('link-contact').addEventListener('click', (e) => {
e.preventDefault();
navigateTo('contact');
});
Paaiškinimas:
currentState
objektas dabar saugo konkretesnę informaciją, pvz., dabartinį puslapį, savavališkus duomenis ir slinkties poziciją. Tai leidžia atlikti išsamesnį būsenos atkūrimą.- Funkcija
updateTheDOM
simuliuoja DOM atnaujinimą. Pakeiskite šabloninę logiką savo tikruoju DOM manipuliavimo kodu. Svarbu tai, kad ji taip pat atkuria slinkties poziciją. history.replaceState
pradinio įkėlimo metu yra svarbus, kad paspaudus mygtuką „atgal“ iškart nebūtų grįžtama į tuščią puslapį.- Pavyzdyje dėl paprastumo naudojamas maršrutizavimas pagal grotažymę (hash-based routing). Realiame projekte greičiausiai naudotumėte patikimesnius maršrutizavimo mechanizmus.
2 pavyzdys: Page Visibility API su podėliavimu (caching)
let cachedDOM = null;
function captureDOM() {
// Klonuoti atitinkamą DOM dalį
const contentElement = document.getElementById('content');
cachedDOM = contentElement.cloneNode(true); // Gilus klonavimas
}
function restoreDOM() {
if (cachedDOM) {
const contentElement = document.getElementById('content');
contentElement.parentNode.replaceChild(cachedDOM, contentElement); // Pakeisti podėlyje esančia versija
cachedDOM = null; // Išvalyti podėlį
} else {
console.warn('No cached DOM to restore.');
}
}
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'hidden') {
captureDOM(); // Užfiksuoti DOM prieš paslepiant
}
if (document.visibilityState === 'visible') {
document.startViewTransition(() => {
restoreDOM(); // Atkurti DOM, kai tampa matomas
});
}
});
// Naudojimo pavyzdys (simuliuoti naršymą)
function navigateAway() {
document.getElementById('content').innerHTML = 'Navigating away...
';
// Simuliuoti delsą (pvz., AJAX užklausa)
setTimeout(() => {
//Realiame projekte čia galėtumėte pereiti į kitą puslapį.
console.log("Simuliuotas išėjimas iš puslapio.");
}, 1000);
}
document.getElementById('navigate').addEventListener('click', navigateAway);
Paaiškinimas:
- Šis pavyzdys orientuotas į DOM klonavimą ir atkūrimą. Tai supaprastintas metodas, kuris gali netikti visiems scenarijams, ypač sudėtingoms SPA.
- Funkcija
captureDOM
klonuoja#content
elementą. Gilus klonavimas yra būtinas, kad būtų užfiksuoti visi antriniai elementai ir jų atributai. - Funkcija
restoreDOM
pakeičia esamą#content
podėlyje esančia versija. - Funkcija
navigateAway
simuliuoja naršymą (paprastai ją pakeistumėte tikrąja naršymo logika).
Papildomi aspektai
1. Tarp skirtingų domenų (cross-origin) esantys perėjimai
Vaizdo perėjimai pirmiausia skirti perėjimams toje pačioje kilmės vietoje (angl. same origin). Tarp skirtingų domenų (angl. cross-origin) esantys perėjimai (pvz., perėjimas tarp skirtingų domenų) paprastai yra sudėtingesni ir gali reikalauti kitokių metodų, tokių kaip „iframe“ naudojimas arba atvaizdavimas serveryje (angl. server-side rendering).
2. Našumo optimizavimas
Vaizdo perėjimai gali paveikti našumą, jei jie įgyvendinami neatsargiai. Optimizuokite perėjimus:
- Sumažindami pereinamųjų DOM elementų dydį: Mažesni DOM elementai lemia greitesnius perėjimus.
- Naudodami aparatinį spartinimą: Naudokite CSS savybes, kurios aktyvuoja aparatinį spartinimą (pvz.,
transform: translate3d(0, 0, 0);
). - Uždelsdami perėjimus (debouncing): Uždelskite perėjimų paleidimo logiką, kad išvengtumėte perteklinių perėjimų, kai vartotojas greitai naršo tarp puslapių.
3. Prieinamumas
Užtikrinkite, kad vaizdo perėjimai būtų prieinami vartotojams su negalia. Suteikite alternatyvius naršymo būdus, jei perėjimai trikdo. Apsvarstykite galimybę naudoti ARIA atributus, kad suteiktumėte papildomo konteksto ekrano skaitytuvams.
Realūs pavyzdžiai ir naudojimo atvejai
- El. prekybos produktų galerijos: Sklandūs perėjimai tarp produktų paveikslėlių.
- Naujienų straipsniai: Sklandi navigacija tarp skirtingų straipsnio skilčių.
- Interaktyvios prietaisų skydeliai: Sklandūs perėjimai tarp skirtingų duomenų vizualizacijų.
- Mobiliųjų programėlių tipo navigacija interneto aplikacijose: Įprastų programėlių perėjimų imitavimas naršyklėje.
Išvados
CSS vaizdo perėjimai, derinami su būsenos išsaugojimo ir animacijos atkūrimo metodais, siūlo galingą būdą pagerinti interneto aplikacijų vartotojo patirtį. Kruopščiai valdydami naršyklės istoriją ir pasitelkdami tokius API kaip Page Visibility API, kūrėjai gali sukurti sklandžius ir vizualiai patrauklius perėjimus, dėl kurių interneto aplikacijos atrodo jautresnės ir labiau įtraukiančios. Bręstant ir plačiau palaikant „View Transition“ API, jis neabejotinai taps esminiu įrankiu šiuolaikiniame interneto kūrime.