যদি আমি আপনাকে বলি, একাধিক ভিউপোর্ট আছে।
BRRRRAAAAAAAMMMMMMMMMM
এবং আপনি এই মুহূর্তে যে ভিউপোর্টটি ব্যবহার করছেন তা আসলে একটি ভিউপোর্টের ভিউপোর্ট।
BRRRRAAAAAAAMMMMMMMMMM
এবং কখনও কখনও, DOM আপনাকে যে ডেটা দেয় তা সেই ভিউপোর্টগুলির একটিকে বোঝায় এবং অন্যটিকে নয়।
BRRRRAAAAM… অপেক্ষা কি?
এটা সত্য, একবার দেখুন:
লেআউট ভিউপোর্ট বনাম ভিজ্যুয়াল ভিউপোর্ট
উপরের ভিডিওটি একটি ওয়েব পৃষ্ঠাকে স্ক্রোল করা এবং চিমটি-জুম করা দেখায়, সাথে ডানদিকে একটি মিনি-ম্যাপ পৃষ্ঠার মধ্যে ভিউপোর্টের অবস্থান দেখায়৷
নিয়মিত স্ক্রোলিং করার সময় জিনিসগুলি বেশ সোজা হয়ে যায়। সবুজ এলাকা লেআউট ভিউপোর্টের প্রতিনিধিত্ব করে, কোন position: fixed
আইটেম লেগে থাকে।
যখন চিমটি-জুমিং চালু করা হয় তখন জিনিসগুলি অদ্ভুত হয়ে যায়। লাল বাক্সটি ভিজ্যুয়াল ভিউপোর্টের প্রতিনিধিত্ব করে, যা আমরা আসলে দেখতে পাই সেই পৃষ্ঠার অংশ। position: fixed
উপাদানগুলি যেখানে ছিল সেখানেই থাকে, লেআউট ভিউপোর্টের সাথে সংযুক্ত। আমরা যদি লেআউট ভিউপোর্টের একটি সীমানায় প্যান করি তবে এটি লেআউট ভিউপোর্টটিকে এর সাথে টেনে নিয়ে যায়।
সামঞ্জস্যের উন্নতি
দুর্ভাগ্যবশত ওয়েব এপিআইগুলি তারা কোন ভিউপোর্ট উল্লেখ করে তার পরিপ্রেক্ষিতে অসামঞ্জস্যপূর্ণ, এবং তারা ব্রাউজার জুড়েও বেমানান।
উদাহরণস্বরূপ, element.getBoundingClientRect().y
লেআউট ভিউপোর্টের মধ্যে অফসেট প্রদান করে। এটা চমৎকার, কিন্তু আমরা প্রায়ই পৃষ্ঠার মধ্যে অবস্থান চাই, তাই আমরা লিখি:
element.getBoundingClientRect().y + window.scrollY
যাইহোক, অনেক ব্রাউজার window.scrollY
এর জন্য ভিজ্যুয়াল ভিউপোর্ট ব্যবহার করে, যার অর্থ ব্যবহারকারী যখন পিঞ্চ-জুম করে তখন উপরের কোডটি ভেঙে যায়।
Chrome 61 পরিবর্তে লেআউট ভিউপোর্ট উল্লেখ করার জন্য window.scrollY
পরিবর্তন করে, যার অর্থ উপরের কোডটি পিঞ্চ-জুম করলেও কাজ করে। প্রকৃতপক্ষে, ব্রাউজারগুলি বিন্যাস ভিউপোর্ট উল্লেখ করতে ধীরে ধীরে সমস্ত অবস্থানগত বৈশিষ্ট্য পরিবর্তন করছে।
একটি নতুন সম্পত্তি বাদে…
স্ক্রিপ্টে ভিজ্যুয়াল ভিউপোর্ট প্রকাশ করা
একটি নতুন API ভিজ্যুয়াল ভিউপোর্টকে window.visualViewport
হিসাবে প্রকাশ করে। এটি ক্রস-ব্রাউজার অনুমোদন সহ একটি খসড়া বৈশিষ্ট্য , এবং এটি Chrome 61-এ অবতরণ করছে৷
console.log(window.visualViewport.width);
window.visualViewport
আমাদের যা দেয় তা এখানে:
visualViewport বৈশিষ্ট্য | |
---|---|
offsetLeft | সিএসএস পিক্সেলে ভিজ্যুয়াল ভিউপোর্টের বাম প্রান্ত এবং লেআউট ভিউপোর্টের মধ্যে দূরত্ব। |
offsetTop | সিএসএস পিক্সেলে ভিজ্যুয়াল ভিউপোর্টের উপরের প্রান্ত এবং লেআউট ভিউপোর্টের মধ্যে দূরত্ব। |
pageLeft | সিএসএস পিক্সেলে ভিজ্যুয়াল ভিউপোর্টের বাম প্রান্ত এবং নথির বাম সীমানার মধ্যে দূরত্ব। |
pageTop | CSS পিক্সেলে ভিজ্যুয়াল ভিউপোর্টের উপরের প্রান্ত এবং নথির উপরের সীমানার মধ্যে দূরত্ব। |
width | CSS পিক্সেলে ভিজ্যুয়াল ভিউপোর্টের প্রস্থ। |
height | CSS পিক্সেলে ভিজ্যুয়াল ভিউপোর্টের উচ্চতা। |
scale | পিঞ্চ-জুমিং দ্বারা প্রয়োগ করা স্কেল। জুম করার কারণে বিষয়বস্তুর আকার দ্বিগুণ হলে, এটি 2 ফেরত দেবে। এটি devicePixelRatio দ্বারা প্রভাবিত হয় না। |
এছাড়াও কয়েকটি ঘটনা রয়েছে:
window.visualViewport.addEventListener('resize', listener);
visualViewport ইভেন্ট | |
---|---|
resize | width , height , বা scale পরিবর্তন হলে বহিস্কার করা হয়। |
scroll | offsetLeft বা offsetTop পরিবর্তন হলে বহিস্কার করা হয়। |
ডেমো
এই নিবন্ধের শুরুতে ভিডিওটি visualViewport
ব্যবহার করে তৈরি করা হয়েছে, এটি Chrome 61+ এ দেখুন । এটি visualViewport
ব্যবহার করে মিনি-ম্যাপটিকে ভিজ্যুয়াল ভিউপোর্টের উপরের-ডানে আটকে রাখে এবং একটি বিপরীত স্কেল প্রয়োগ করে যাতে এটি চিমটি-জুম করা সত্ত্বেও সর্বদা একই আকারে প্রদর্শিত হয়।
গোটচাস
ইভেন্টগুলি শুধুমাত্র তখনই জ্বলে যখন ভিজ্যুয়াল ভিউপোর্ট পরিবর্তন হয়
এটি বলার মতো একটি সুস্পষ্ট জিনিস মনে হয়, কিন্তু আমি যখন প্রথম visualViewport
সাথে খেলেছিলাম তখন এটি আমাকে ধরে ফেলেছিল।
যদি লেআউট ভিউপোর্টের আকার পরিবর্তন করা হয় কিন্তু ভিজ্যুয়াল ভিউপোর্ট না হয়, তাহলে আপনি একটি resize
ইভেন্ট পাবেন না। যাইহোক, লেআউট ভিউপোর্টের প্রস্থ/উচ্চতা পরিবর্তন না করে ভিজ্যুয়াল ভিউপোর্টের আকার পরিবর্তন করা অস্বাভাবিক।
আসল গোছা স্ক্রলিং করা হয়। যদি স্ক্রোলিং ঘটে, কিন্তু ভিজ্যুয়াল ভিউপোর্ট লেআউট ভিউপোর্টের সাপেক্ষে স্থির থাকে, আপনি visualViewport
এ একটি scroll
ইভেন্ট পাবেন না এবং এটি সত্যিই সাধারণ। নিয়মিত ডকুমেন্ট স্ক্রল করার সময়, ভিজ্যুয়াল ভিউপোর্ট লেআউট ভিউপোর্টের উপরের-বাম দিকে লক থাকে, তাই scroll
visualViewport
ফায়ার করে না ।
আপনি যদি pageTop
এবং pageLeft
সহ ভিজ্যুয়াল ভিউপোর্টের সমস্ত পরিবর্তন সম্পর্কে শুনতে চান, তাহলে আপনাকে উইন্ডোর স্ক্রোল ইভেন্টটিও শুনতে হবে:
visualViewport.addEventListener('scroll', update);
visualViewport.addEventListener('resize', update);
window.addEventListener('scroll', update);
একাধিক শ্রোতাদের সাথে সদৃশ কাজ এড়িয়ে চলুন
উইন্ডোতে scroll
এবং resize
শোনার মতোই, আপনি ফলস্বরূপ কিছু ধরণের "আপডেট" ফাংশন কল করতে পারেন। যাইহোক, এই ঘটনাগুলির অনেকগুলি একই সময়ে ঘটতে সাধারণ৷ ব্যবহারকারী যদি উইন্ডোটির আকার পরিবর্তন করে, তবে এটি resize
ট্রিগার করবে, তবে প্রায়শই scroll
। কর্মক্ষমতা উন্নত করতে, একাধিকবার পরিবর্তন পরিচালনা করা এড়িয়ে চলুন:
// Add listeners
visualViewport.addEventListener('scroll', update);
visualViewport.addEventListener('resize', update);
addEventListener('scroll', update);
let pendingUpdate = false;
function update() {
// If we're already going to handle an update, return
if (pendingUpdate) return;
pendingUpdate = true;
// Use requestAnimationFrame so the update happens before next render
requestAnimationFrame(() => {
pendingUpdate = false;
// Handle update here
});
}
আমি এর জন্য একটি বিশেষ সমস্যা দায়ের করেছি , কারণ আমি মনে করি একটি ভাল উপায় হতে পারে, যেমন একটি একক update
ইভেন্ট।
ইভেন্ট হ্যান্ডলাররা কাজ করে না
একটি Chrome বাগের কারণে , এটি কাজ করে না :
বগি - একটি ইভেন্ট হ্যান্ডলার ব্যবহার করে
visualViewport.onscroll = () => console.log('scroll!');
পরিবর্তে:
কাজ করে - একটি ইভেন্ট লিসেনার ব্যবহার করে
visualViewport.addEventListener('scroll', () => console.log('scroll'));
অফসেট মান বৃত্তাকার হয়
আমি মনে করি (ভাল, আমি আশা করি) এটি আরেকটি ক্রোম বাগ ।
offsetLeft
এবং offsetTop
বৃত্তাকার, যা ব্যবহারকারী একবার জুম ইন করার পরে বেশ ভুল। আপনি ডেমো চলাকালীন এটির সমস্যাগুলি দেখতে পারেন - যদি ব্যবহারকারী জুম করে এবং ধীরে ধীরে প্যান করে, মিনি-ম্যাপ আনজুম করা পিক্সেলগুলির মধ্যে স্ন্যাপ করে ।
ইভেন্ট হার ধীর
অন্যান্য resize
এবং scroll
ইভেন্টের মতো, এগুলি প্রতিটি ফ্রেমে, বিশেষত মোবাইলে ফায়ার করে না। আপনি ডেমো চলাকালীন এটি দেখতে পারেন - একবার আপনি জুম চিমটি করলে, মিনি-ম্যাপে ভিউপোর্টে লক থাকতে সমস্যা হয়।
অ্যাক্সেসযোগ্যতা
ডেমোতে আমি ব্যবহারকারীর পিঞ্চ-জুমকে প্রতিহত করতে visualViewport
ব্যবহার করেছি। এই বিশেষ ডেমোর জন্য এটি বোধগম্য, তবে ব্যবহারকারীর জুম ইন করার ইচ্ছাকে ওভাররাইড করে এমন কিছু করার আগে আপনার সাবধানে চিন্তা করা উচিত।
visualViewport
অ্যাক্সেসযোগ্যতা উন্নত করতে ব্যবহার করা যেতে পারে। উদাহরণস্বরূপ, যদি ব্যবহারকারী জুম ইন করে, আপনি আলংকারিক position: fixed
আইটেমগুলি, ব্যবহারকারীর পথ থেকে বের করে আনতে। কিন্তু আবার, সতর্ক থাকুন আপনি এমন কিছু লুকাচ্ছেন না যা ব্যবহারকারী ঘনিষ্ঠভাবে দেখার চেষ্টা করছেন।
ব্যবহারকারী যখন জুম ইন করে তখন আপনি একটি বিশ্লেষণ পরিষেবাতে পোস্ট করার কথা বিবেচনা করতে পারেন৷ এটি আপনাকে ডিফল্ট জুম স্তরে ব্যবহারকারীদের অসুবিধা হয় এমন পৃষ্ঠাগুলি সনাক্ত করতে সহায়তা করতে পারে৷
visualViewport.addEventListener('resize', () => {
if (visualViewport.scale > 1) {
// Post data to analytics service
}
});
আর এটাই! visualViewport
একটি সুন্দর ছোট API যা পথের সাথে সামঞ্জস্যের সমস্যাগুলি সমাধান করে।