जब दो अलग-अलग दस्तावेज़ों के बीच व्यू का ट्रांज़िशन होता है, तो इसे क्रॉस-दस्तावेज़ व्यू ट्रांज़िशन कहा जाता है. आम तौर पर, ऐसा कई पेज वाले ऐप्लिकेशन (एमपीए) के मामले में होता है. Chrome 126 और Chrome में, क्रॉस-डॉक्यूमेंट व्यू ट्रांज़िशन काम करते हैं.
ब्राउज़र सहायता
- अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
- अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
- अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
- अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
क्रॉस-डॉक्यूमेंट व्यू ट्रांज़िशन, एक ही दस्तावेज़ के व्यू ट्रांज़िशन की तरह ही एक जैसे बिल्डिंग ब्लॉक और सिद्धांतों पर निर्भर होते हैं, जो खास तौर पर सोच-समझकर किए जाते हैं:
- ब्राउज़र उन एलिमेंट के स्नैपशॉट लेता है जिनमें पुराने और नए, दोनों पेजों पर यूनीक
view-transition-name
होता है. - रेंडरिंग बंद होने पर, डीओएम अपडेट हो जाता है.
- और आखिर में, ये ट्रांज़िशन सीएसएस ऐनिमेशन की मदद से होते हैं.
एक ही दस्तावेज़ के व्यू ट्रांज़िशन से तुलना करने पर, क्या अलग होता है: क्रॉस-दस्तावेज़ व्यू ट्रांज़िशन के साथ, व्यू ट्रांज़िशन शुरू करने के लिए, आपको document.startViewTransition
को कॉल करने की ज़रूरत नहीं होती. इसके बजाय, क्रॉस-दस्तावेज़ व्यू ट्रांज़िशन के लिए ट्रिगर, एक पेज से दूसरे पेज पर जाने वाले एक ही ऑरिजिन वाला नेविगेशन होता है. यह कार्रवाई आम तौर पर आपकी वेबसाइट के उपयोगकर्ता की ओर से लिंक पर क्लिक करके की जाती है.
दूसरे शब्दों में, दो दस्तावेज़ों के बीच व्यू ट्रांज़िशन शुरू करने के लिए, कॉल करने के लिए कोई एपीआई उपलब्ध नहीं है. हालांकि, दो शर्तें पूरी करनी होंगी:
- दोनों दस्तावेज़ एक ही ऑरिजिन पर होने चाहिए.
- व्यू ट्रांज़िशन के लिए, दोनों पेजों को ऑप्ट-इन करना होगा.
इस दस्तावेज़ में इन दोनों शर्तों के बारे में आगे बताया गया है.
क्रॉस-दस्तावेज़ व्यू ट्रांज़िशन, सिर्फ़ एक ऑरिजिन वाले नेविगेशन तक ही सीमित हैं
क्रॉस-दस्तावेज़ व्यू ट्रांज़िशन, सिर्फ़ एक ही ऑरिजिन वाले नेविगेशन तक सीमित हैं. किसी नेविगेशन को एक ही ऑरिजिन तब माना जाता है, जब इसमें शामिल दोनों पेजों की शुरुआत एक ही हो.
किसी पेज का ऑरिजिन, इस्तेमाल की गई स्कीम, होस्टनेम, और पोर्ट को मिलाकर किया जाता है, जैसा कि web.dev पर बताया गया है.
उदाहरण के लिए, developer.chrome.com
से developer.chrome.com/blog
पर नेविगेट करते समय, आपके पास क्रॉस-दस्तावेज़ व्यू ट्रांज़िशन हो सकता है, क्योंकि वे एक ही ऑरिजिन वाले होते हैं.
developer.chrome.com
से www.chrome.com
पर नेविगेट करते समय, आपके पास यह ट्रांज़िशन नहीं हो सकता, क्योंकि वे क्रॉस-ऑरिजिन और सेम-साइट हैं.
क्रॉस-दस्तावेज़ व्यू ट्रांज़िशन के लिए ऑप्ट-इन किया जा सकता है
दो दस्तावेज़ों के बीच क्रॉस-दस्तावेज़ व्यू ट्रांज़िशन के लिए, इस सुविधा का इस्तेमाल करने वाले दोनों पेजों को ऑप्ट-इन करना होगा. ऐसा सीएसएस में, @view-transition
के नियम की मदद से किया जाता है.
@view-transition
के नियम में, navigation
डिस्क्रिप्टर को auto
पर सेट करें, ताकि क्रॉस-दस्तावेज़ और एक जैसे ऑरिजिन वाले नेविगेशन के लिए व्यू ट्रांज़िशन चालू किए जा सकें.
@view-transition {
navigation: auto;
}
navigation
डिस्क्रिप्टर को auto
पर सेट करने का मतलब है कि आपने इन NavigationType के लिए व्यू ट्रांज़िशन की अनुमति देने के लिए ऑप्ट इन किया है:
traverse
push
याreplace
, अगर उपयोगकर्ता ने ब्राउज़र यूज़र इंटरफ़ेस (यूआई) मैकेनिज़्म के ज़रिए चालू नहीं किया था.
auto
में शामिल नहीं किए गए नेविगेशन का इस्तेमाल, यूआरएल पता बार का इस्तेमाल करके नेविगेट करने या किसी बुकमार्क पर क्लिक करने के साथ-साथ, उपयोगकर्ता या स्क्रिप्ट को फिर से लोड करने के दौरान किया जा सकता है.
अगर Chrome के मामले में, नेविगेशन में चार सेकंड से ज़्यादा समय लगता है, तो TimeoutError
DOMException
के साथ व्यू ट्रांज़िशन को स्किप कर दिया जाता है.
क्रॉस-दस्तावेज़ व्यू ट्रांज़िशन का डेमो
नीचे दिया गया यह डेमो देखें, जिसमें स्टैक नेविगेटर डेमो बनाने के लिए व्यू ट्रांज़िशन का इस्तेमाल किया गया है. यहां document.startViewTransition()
पर कोई कॉल नहीं किया गया है. व्यू ट्रांज़िशन एक पेज से दूसरे पेज पर जाने पर ट्रिगर होते हैं.
क्रॉस-दस्तावेज़ व्यू ट्रांज़िशन को पसंद के मुताबिक बनाना
क्रॉस-डॉक्यूमेंट व्यू ट्रांज़िशन को पसंद के मुताबिक बनाने के लिए, वेब प्लैटफ़ॉर्म की कुछ सुविधाओं का इस्तेमाल किया जा सकता है.
ये सुविधाएं, व्यू ट्रांज़िशन एपीआई की खास बातों का हिस्सा नहीं हैं. हालांकि, इन्हें इसके साथ इस्तेमाल करने के लिए डिज़ाइन किया गया है.
pageswap
और pagereveal
इवेंट
ब्राउज़र सहायता
- अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
- अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
- अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
- अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
क्रॉस-दस्तावेज़ व्यू ट्रांज़िशन को पसंद के मुताबिक बनाने के लिए, एचटीएमएल स्पेसिफ़िकेशन में दो नए इवेंट शामिल किए गए हैं: pageswap
और pagereveal
.
ये दोनों इवेंट, एक ही ऑरिजिन के हर क्रॉस-डॉक्यूमेंट नेविगेशन के लिए ट्रिगर होते हैं. इससे कोई फ़र्क़ नहीं पड़ता कि व्यू का ट्रांज़िशन होने वाला है या नहीं. अगर दो पेजों के बीच व्यू का ट्रांज़िशन होने वाला है, तो इन इवेंट की viewTransition
प्रॉपर्टी का इस्तेमाल करके, ViewTransition
ऑब्जेक्ट को ऐक्सेस किया जा सकता है.
- किसी पेज का आखिरी फ़्रेम रेंडर होने से पहले,
pageswap
इवेंट ट्रिगर होता है. इसका उपयोग पुराने स्नैपशॉट लिए जाने से ठीक पहले आउटगोइंग पेज पर आखिरी समय में कुछ बदलाव करने के लिए किया जा सकता है. pagereveal
इवेंट, शुरू किए जाने या फिर से चालू किए जाने के बाद, लेकिन रेंडर करने के पहले अवसर से पहले, पेज पर ट्रिगर होता है. इसकी मदद से, नए स्नैपशॉट लिए जाने से पहले, नए पेज को अपनी पसंद के मुताबिक बनाया जा सकता है.
उदाहरण के लिए, इन इवेंट का इस्तेमाल view-transition-name
की कुछ वैल्यू को तुरंत सेट करने या बदलने के लिए किया जा सकता है. इसके अलावा, डेटा को एक दस्तावेज़ से दूसरे दस्तावेज़ में पास करने के लिए भी ऐसा किया जा सकता है. इसके लिए, sessionStorage
से डेटा को लिखकर और पढ़ें, ताकि व्यू के चालू होने से पहले उसे कस्टमाइज़ किया जा सके.
let lastClickX, lastClickY;
document.addEventListener('click', (event) => {
if (event.target.tagName.toLowerCase() === 'a') return;
lastClickX = event.clientX;
lastClickY = event.clientY;
});
// Write position to storage on old page
window.addEventListener('pageswap', (event) => {
if (event.viewTransition && lastClick) {
sessionStorage.setItem('lastClickX', lastClickX);
sessionStorage.setItem('lastClickY', lastClickY);
}
});
// Read position from storage on new page
window.addEventListener('pagereveal', (event) => {
if (event.viewTransition) {
lastClickX = sessionStorage.getItem('lastClickX');
lastClickY = sessionStorage.getItem('lastClickY');
}
});
अगर आप चाहें, तो दोनों इवेंट में ट्रांज़िशन को स्किप कर सकते हैं.
window.addEventListener("pagereveal", async (e) => {
if (e.viewTransition) {
if (goodReasonToSkipTheViewTransition()) {
e.viewTransition.skipTransition();
}
}
}
pageswap
और pagereveal
में ViewTransition
ऑब्जेक्ट दो अलग-अलग ऑब्जेक्ट हैं. वे अलग-अलग वादों को भी अलग तरीके से हैंडल करती हैं:
pageswap
: दस्तावेज़ के छिपे होने पर, पुरानाViewTransition
ऑब्जेक्ट स्किप कर दिया जाता है. ऐसा होने पर,viewTransition.ready
अनुरोध अस्वीकार कर देता है औरviewTransition.finished
अनुरोध अस्वीकार कर देता है.pagereveal
:updateCallBack
प्रॉमिस पहले ही रिज़ॉल्व हो गया है.viewTransition.ready
औरviewTransition.finished
प्रॉमिस का इस्तेमाल किया जा सकता है.
नेविगेशन चालू करने की जानकारी
ब्राउज़र सहायता
- अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
- अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
- अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
- अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
pageswap
और pagereveal
, दोनों इवेंट में, पुराने और नए पेजों के यूआरएल के आधार पर भी कार्रवाई की जा सकती है.
उदाहरण के लिए, MPA स्टैक नेविगेटर में इस्तेमाल किए जाने वाले ऐनिमेशन का टाइप, नेविगेशन पाथ पर निर्भर करता है:
- खास जानकारी वाले पेज से ज़्यादा जानकारी वाले पेज पर जाने पर, नए कॉन्टेंट को दाईं से बाईं ओर स्लाइड करना होगा.
- ज़्यादा जानकारी वाले पेज से खास जानकारी वाले पेज पर जाने के लिए, पुराने कॉन्टेंट को बाईं से दाईं ओर स्लाइड करें.
ऐसा करने के लिए, आपको उस नेविगेशन से जुड़ी जानकारी की ज़रूरत होगी जो pageswap
के मामले में होने वाली हो या pagereveal
के मामले में अभी हुई हो.
इसके लिए, ब्राउज़र अब NavigationActivation
ऑब्जेक्ट दिखा सकते हैं जिनमें एक ही ऑरिजिन वाले नेविगेशन की जानकारी होती है. यह ऑब्जेक्ट इस्तेमाल किए गए नेविगेशन टाइप, डेस्टिनेशन के मौजूदा इतिहास, और डेस्टिनेशन के इतिहास की आखिरी एंट्री दिखाता है, जैसा कि नेविगेशन एपीआई से navigation.entries()
में मिला है.
चालू किए गए पेज पर, navigation.activation
के ज़रिए इस ऑब्जेक्ट को ऐक्सेस किया जा सकता है. pageswap
इवेंट में, इसे e.activation
से ऐक्सेस किया जा सकता है.
प्रोफ़ाइलों का यह डेमो देखें. इसमें pageswap
और pagereveal
इवेंट में मौजूद NavigationActivation
की जानकारी का इस्तेमाल करके, उन एलिमेंट पर view-transition-name
वैल्यू सेट की जाती हैं जिन्हें व्यू ट्रांज़िशन में शामिल करना ज़रूरी है.
इस तरह, आपको सूची के हर आइटम को view-transition-name
से पहले से सजाना नहीं होगा. इसके बजाय, यह JavaScript का इस्तेमाल करके तुरंत उन एलिमेंट पर कार्रवाई करता है जिन्हें इसकी ज़रूरत होती है.
कोड इस तरह से होता है:
// OLD PAGE LOGIC
window.addEventListener('pageswap', async (e) => {
if (e.viewTransition) {
const targetUrl = new URL(e.activation.entry.url);
// Navigating to a profile page
if (isProfilePage(targetUrl)) {
const profile = extractProfileNameFromUrl(targetUrl);
// Set view-transition-name values on the clicked row
document.querySelector(`#${profile} span`).style.viewTransitionName = 'name';
document.querySelector(`#${profile} img`).style.viewTransitionName = 'avatar';
// Remove view-transition-names after snapshots have been taken
// (this to deal with BFCache)
await e.viewTransition.finished;
document.querySelector(`#${profile} span`).style.viewTransitionName = 'none';
document.querySelector(`#${profile} img`).style.viewTransitionName = 'none';
}
}
});
// NEW PAGE LOGIC
window.addEventListener('pagereveal', async (e) => {
if (e.viewTransition) {
const fromURL = new URL(navigation.activation.from.url);
const currentURL = new URL(navigation.activation.entry.url);
// Navigating from a profile page back to the homepage
if (isProfilePage(fromURL) && isHomePage(currentURL)) {
const profile = extractProfileNameFromUrl(currentURL);
// Set view-transition-name values on the elements in the list
document.querySelector(`#${profile} span`).style.viewTransitionName = 'name';
document.querySelector(`#${profile} img`).style.viewTransitionName = 'avatar';
// Remove names after snapshots have been taken
// so that we're ready for the next navigation
await e.viewTransition.ready;
document.querySelector(`#${profile} span`).style.viewTransitionName = 'none';
document.querySelector(`#${profile} img`).style.viewTransitionName = 'none';
}
}
});
व्यू ट्रांज़िशन के चलने के बाद, कोड view-transition-name
वैल्यू को हटाकर अपने-आप खाली हो जाता है. इस तरह पेज क्रम से चलने वाले नेविगेशन के लिए तैयार होता है और इतिहास के ट्रैवर्सल को भी हैंडल कर सकता है.
इसमें मदद करने के लिए, इस यूटिलिटी फ़ंक्शन का इस्तेमाल करें जो view-transition-name
को कुछ समय के लिए सेट करता है.
const setTemporaryViewTransitionNames = async (entries, vtPromise) => {
for (const [$el, name] of entries) {
$el.style.viewTransitionName = name;
}
await vtPromise;
for (const [$el, name] of entries) {
$el.style.viewTransitionName = '';
}
}
पिछले कोड को अब इस तरह से आसान बनाया जा सकता है:
// OLD PAGE LOGIC
window.addEventListener('pageswap', async (e) => {
if (e.viewTransition) {
const targetUrl = new URL(e.activation.entry.url);
// Navigating to a profile page
if (isProfilePage(targetUrl)) {
const profile = extractProfileNameFromUrl(targetUrl);
// Set view-transition-name values on the clicked row
// Clean up after the page got replaced
setTemporaryViewTransitionNames([
[document.querySelector(`#${profile} span`), 'name'],
[document.querySelector(`#${profile} img`), 'avatar'],
], e.viewTransition.finished);
}
}
});
// NEW PAGE LOGIC
window.addEventListener('pagereveal', async (e) => {
if (e.viewTransition) {
const fromURL = new URL(navigation.activation.from.url);
const currentURL = new URL(navigation.activation.entry.url);
// Navigating from a profile page back to the homepage
if (isProfilePage(fromURL) && isHomePage(currentURL)) {
const profile = extractProfileNameFromUrl(currentURL);
// Set view-transition-name values on the elements in the list
// Clean up after the snapshots have been taken
setTemporaryViewTransitionNames([
[document.querySelector(`#${profile} span`), 'name'],
[document.querySelector(`#${profile} img`), 'avatar'],
], e.viewTransition.ready);
}
}
});
रेंडर ब्लॉक करने की सुविधा की मदद से, कॉन्टेंट के लोड होने का इंतज़ार करें
ब्राउज़र सहायता
- अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
- अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
- अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
- अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है
कुछ मामलों में, हो सकता है कि आप पेज के पहले रेंडर को तब तक रोकना चाहें जब तक कि कोई खास एलिमेंट नए DOM में मौजूद न हो. इससे फ़्लैश होने से बचा जाता है और यह पक्का किया जाता है कि ऐनिमेशन वाली स्थिति स्थिर है.
<head>
में, एक या एक से ज़्यादा एलिमेंट आईडी तय करें, जो पेज को पहली बार रेंडर होने से पहले मौजूद होने चाहिए. इसके लिए, इन मेटा टैग का इस्तेमाल करें.
<link rel="expect" blocking="render" href="#section1">
इस मेटा टैग का मतलब है कि एलिमेंट, डीओएम में मौजूद होना चाहिए, न कि कॉन्टेंट को लोड किया जाना चाहिए. उदाहरण के लिए, इमेज के साथ डीओएम ट्री में बताए गए id
के साथ सिर्फ़ <img>
टैग का मौजूद होना, शर्त के 'सही' का आकलन करने के लिए काफ़ी है. इमेज अब भी लोड हो सकती है.
रेंडर को ब्लॉक करने के बारे में पूरी जानकारी देने से पहले ध्यान रखें कि इंक्रीमेंटल रेंडरिंग वेब का बुनियादी पहलू है. इसलिए, रेंडरिंग को ब्लॉक करते समय सावधानी बरतें. रेंडरिंग को ब्लॉक करने से होने वाले असर का आकलन, अलग-अलग पहलुओं को ध्यान में रखकर किया जाना चाहिए. डिफ़ॉल्ट रूप से, blocking=render
का इस्तेमाल तब तक न करें, जब तक आप अपनी वेबसाइट की परफ़ॉर्मेंस की अहम जानकारी के असर को मेज़र करके, उपयोगकर्ताओं पर पड़ने वाले असर को मेज़र और नाप सकें.
क्रॉस-दस्तावेज़ व्यू ट्रांज़िशन में ट्रांज़िशन टाइप देखें
क्रॉस-दस्तावेज़ व्यू ट्रांज़िशन में, ट्रांज़िशन टाइप देखने की सुविधा भी काम करती है. इसकी मदद से, ऐनिमेशन को पसंद के मुताबिक बनाया जा सकता है और कैप्चर किए जा सकने वाले एलिमेंट भी देखे जा सकते हैं.
उदाहरण के लिए, खोज नतीजों को पेजों में बांटने के दौरान अगले या पिछले पेज पर जाने के लिए, हो सकता है कि आप अलग-अलग ऐनिमेशन का इस्तेमाल करना चाहें. यह इस बात पर निर्भर करता है कि क्रम से ऊपर वाले पेज पर जा रहे हैं या नीचे के पेज पर.
इन टाइप को पहले से सेट करने के लिए, @view-transition
के नियम में ये टाइप जोड़ें:
@view-transition {
navigation: auto;
types: slide, forwards;
}
आसानी से टाइप सेट करने के लिए, pageswap
और pagereveal
इवेंट का इस्तेमाल करके e.viewTransition.types
की वैल्यू में बदलाव करें.
window.addEventListener("pagereveal", async (e) => {
if (e.viewTransition) {
const transitionType = determineTransitionType(navigation.activation.from, navigation.activation.entry);
e.viewTransition.types.add(transitionType);
}
});
टाइप, पुराने पेज पर मौजूद ViewTransition
ऑब्जेक्ट से नए पेज के ViewTransition
ऑब्जेक्ट में अपने-आप नहीं ले जाते. आपको कम से कम नए पेज पर इस्तेमाल करने के लिए टाइप तय करना होगा, ताकि ऐनिमेशन उम्मीद के मुताबिक चल सकें.
इन टाइप का जवाब देने के लिए, एक ही दस्तावेज़ के व्यू ट्रांज़िशन की तरह ही :active-view-transition-type()
स्यूडो-क्लास सिलेक्टर का इस्तेमाल करें
/* Determine what gets captured when the type is forwards or backwards */
html:active-view-transition-type(forwards, backwards) {
:root {
view-transition-name: none;
}
article {
view-transition-name: content;
}
.pagination {
view-transition-name: pagination;
}
}
/* Animation styles for forwards type only */
html:active-view-transition-type(forwards) {
&::view-transition-old(content) {
animation-name: slide-out-to-left;
}
&::view-transition-new(content) {
animation-name: slide-in-from-right;
}
}
/* Animation styles for backwards type only */
html:active-view-transition-type(backwards) {
&::view-transition-old(content) {
animation-name: slide-out-to-right;
}
&::view-transition-new(content) {
animation-name: slide-in-from-left;
}
}
/* Animation styles for reload type only */
html:active-view-transition-type(reload) {
&::view-transition-old(root) {
animation-name: fade-out, scale-down;
}
&::view-transition-new(root) {
animation-delay: 0.25s;
animation-name: fade-in, scale-up;
}
}
टाइप सिर्फ़ किसी चालू व्यू ट्रांज़िशन पर लागू होते हैं. इसलिए, व्यू ट्रांज़िशन खत्म होने पर टाइप अपने-आप हट जाते हैं. इस वजह से, BFCache जैसी सुविधाओं के साथ टाइप अच्छी तरह काम करते हैं.
डेमो
नीचे दिए गए पेज नंबर दिखाने के डेमो में, पेज का कॉन्टेंट उस पेज नंबर के हिसाब से आगे या पीछे स्लाइड होता है जिस पर आप नेविगेट कर रहे हैं.
इस्तेमाल किया जाने वाला ट्रांज़िशन टाइप, pagereveal
और pageswap
इवेंट में, यूआरएल में और उनसे यूआरएल देखकर तय किया जाता है.
const determineTransitionType = (fromNavigationEntry, toNavigationEntry) => {
const currentURL = new URL(fromNavigationEntry.url);
const destinationURL = new URL(toNavigationEntry.url);
const currentPathname = currentURL.pathname;
const destinationPathname = destinationURL.pathname;
if (currentPathname === destinationPathname) {
return "reload";
} else {
const currentPageIndex = extractPageIndexFromPath(currentPathname);
const destinationPageIndex = extractPageIndexFromPath(destinationPathname);
if (currentPageIndex > destinationPageIndex) {
return 'backwards';
}
if (currentPageIndex < destinationPageIndex) {
return 'forwards';
}
return 'unknown';
}
};
सुझाव/राय दें या शिकायत करें
डेवलपर के फ़ीडबैक की हमेशा सराहना की जाती है. शेयर करने के लिए, सुझावों और सवालों के साथ GitHub पर सीएसएस वर्किंग ग्रुप में समस्या दर्ज करें. [css-view-transitions]
से जुड़ी अपनी समस्या प्रीफ़िक्स करें.
अगर आपको किसी गड़बड़ी का सामना करना पड़ता है, तो Chromium में गड़बड़ी की शिकायत करें.