বর্তমান ভিউপোর্টে কোনও ডিওএম উপাদান দৃশ্যমান কিনা তা আমি কীভাবে বলতে পারি?


949

কোনও ডিওএম উপাদান (এইচটিএমএল ডকুমেন্টে) বর্তমানে দৃশ্যমান ( ভিউপোর্টে প্রদর্শিত হবে) তা বলার কোনও কার্যকর উপায় আছে কি ?

(প্রশ্নটি ফায়ারফক্সকে বোঝায়))


দৃশ্যমান দ্বারা আপনি কী বোঝাতে চান তা নির্ভর করে। যদি আপনি বোঝাতে চান যে এটি বর্তমানে পৃষ্ঠায় প্রদর্শিত হয়েছে, স্ক্রোলের অবস্থানটি দেওয়া হয়েছে, আপনি y অফসেট উপাদান এবং বর্তমান স্ক্রোল অবস্থানের ভিত্তিতে এটি গণনা করতে পারেন।
roryf

18
স্পষ্টকরণ: দৃশ্যমান, বর্তমানে প্রদর্শিত আয়তক্ষেত্রের মধ্যে রয়েছে। দৃশ্যমান, যেমন লুকানো বা প্রদর্শনের মতো: কোনওটি নয়? দৃশ্যমান, জেড-অর্ডারে অন্য কোনও কিছুর পিছনে নেই?
অ্যাডাম রাইট

6
বর্তমানে প্রদর্শিত আয়তক্ষেত্রের মধ্যে রয়েছে ধন্যবাদ। পুনরায় তৈরি।
বেনজাইটা

2
নোট করুন যে এখানে সমস্ত উত্তর আপনাকে আইটেমগুলির জন্য একটি মিথ্যা ইতিবাচক উপহার দেবে যা তাদের পিতামাতার উপাদানগুলির দৃশ্যমান ক্ষেত্রের বাইরে (এহ ওভারফ্লো লুকানো সহ) তবে ভিউপোর্ট অঞ্চলের অভ্যন্তরে।
অ্যান্ডি ই

1
এক মিলিয়ন উত্তর রয়েছে এবং বেশিরভাগ হাস্যকরভাবে দীর্ঘ। একটি দ্বি-লাইনারের জন্য এখানে দেখুন
একাকীত্ব

উত্তর:


346

আপডেট: সময় মার্চ করে এবং তাই আমাদের ব্রাউজারগুলি। এই কৌশলটি আর সুপারিশ করা হয়নি এবং আপনার যদি 7 এর আগে ইন্টারনেট এক্সপ্লোরারের সংস্করণ সমর্থন করার প্রয়োজন না হয় তবে আপনার ড্যানের সমাধানটি ব্যবহার করা উচিত ।

আসল সমাধান (এখন পুরানো):

উপাদানটি বর্তমান ভিউপোর্টে পুরোপুরি দৃশ্যমান কিনা তা এটি পরীক্ষা করবে:

function elementInViewport(el) {
  var top = el.offsetTop;
  var left = el.offsetLeft;
  var width = el.offsetWidth;
  var height = el.offsetHeight;

  while(el.offsetParent) {
    el = el.offsetParent;
    top += el.offsetTop;
    left += el.offsetLeft;
  }

  return (
    top >= window.pageYOffset &&
    left >= window.pageXOffset &&
    (top + height) <= (window.pageYOffset + window.innerHeight) &&
    (left + width) <= (window.pageXOffset + window.innerWidth)
  );
}

উপাদানটির কোনও অংশ ভিউপোর্টে দৃশ্যমান কিনা তা নির্ধারণ করতে আপনি এটিকে সহজেই সংশোধন করতে পারেন:

function elementInViewport2(el) {
  var top = el.offsetTop;
  var left = el.offsetLeft;
  var width = el.offsetWidth;
  var height = el.offsetHeight;

  while(el.offsetParent) {
    el = el.offsetParent;
    top += el.offsetTop;
    left += el.offsetLeft;
  }

  return (
    top < (window.pageYOffset + window.innerHeight) &&
    left < (window.pageXOffset + window.innerWidth) &&
    (top + height) > window.pageYOffset &&
    (left + width) > window.pageXOffset
  );
}

1
মূল ফাংশন পোস্ট করা একটি ভুল ছিল। পুনরায় নিয়োগের আগে প্রস্থ / উচ্চতা সংরক্ষণ করা দরকার ...
প্রেস্টল

15
যদি উপাদানটি কোনও স্ক্রোলযোগ্য ডিভের মধ্যে থাকে এবং একটি ভিউয়ের বাইরে স্ক্রোল হয় তবে কি হবে ??
amartynov

2
দয়া করে নীচের স্ক্রিপ্টটির একটি নতুন সংস্করণ পর্যালোচনা করুন
ড্যান

1
@ অমর্ত্যনভের প্রশ্ন সম্পর্কেও কৌতূহল। পূর্বপুরুষের উপাদানটির অতিরিক্ত প্রবাহের কারণে কোনও উপাদান লুকানো আছে কীভাবে কেউ জানেন কীভাবে? বোনাস যদি এটি সনাক্ত করা যায় যে শিশুটি কতটা গভীরভাবে বাসা বেঁধেছে তা নির্বিশেষে।
এরিক নুগেইন

1
@ ডিএডম্যান এনওএম-এর মাধ্যমে পুনরাবৃত্তি করা কুখ্যাতভাবে ধীর slow এটি যথেষ্ট কারণ, তবে ব্রাউজার বিক্রেতারাও getBoundingClientRectবিশেষত উপাদান সমন্বয়গুলি সন্ধানের উদ্দেশ্যে তৈরি করেছেন ... আমরা কেন এটি ব্যবহার করব না?
প্রেস্টল

1402

এখন বেশিরভাগ ব্রাউজারগুলি getBoundingClientRect পদ্ধতি সমর্থন করে যা সেরা অনুশীলনে পরিণত হয়েছে। পুরানো উত্তরটি ব্যবহার করা খুব ধীর , সঠিক নয় এবং এর বেশ কয়েকটি বাগ রয়েছে

সঠিক হিসাবে নির্বাচিত সমাধান প্রায় কখনও সুনির্দিষ্ট হয় না । আপনি এর বাগগুলি সম্পর্কে আরও পড়তে পারেন ।


এই সমাধানটি ইন্টারনেট এক্সপ্লোরার 7 (এবং তারপরে), আইওএস 5 (এবং তারপরে) সাফারি, অ্যান্ড্রয়েড 2.0 (একলায়ার) এবং পরে ব্ল্যাকবেরি, অপেরা মোবাইল এবং ইন্টারনেট এক্সপ্লোরার মোবাইল 9 এ পরীক্ষা করা হয়েছিল


function isElementInViewport (el) {

    // Special bonus for those using jQuery
    if (typeof jQuery === "function" && el instanceof jQuery) {
        el = el[0];
    }

    var rect = el.getBoundingClientRect();

    return (
        rect.top >= 0 &&
        rect.left >= 0 &&
        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /* or $(window).height() */
        rect.right <= (window.innerWidth || document.documentElement.clientWidth) /* or $(window).width() */
    );
}

ব্যবহারবিধি:

আপনি নিশ্চিত হতে পারেন যে উপরের প্রদত্ত ফাংশনটি যখন ডেকে আনা হচ্ছে ঠিক সেই মুহুর্তে সঠিক উত্তর দেয় তবে কোনও ইভেন্ট হিসাবে উপাদানটির দৃশ্যমানতা ট্র্যাকিংয়ের কী?

নিম্নলিখিত <body>ট্যাগটি আপনার ট্যাগের নীচে রাখুন :

function onVisibilityChange(el, callback) {
    var old_visible;
    return function () {
        var visible = isElementInViewport(el);
        if (visible != old_visible) {
            old_visible = visible;
            if (typeof callback == 'function') {
                callback();
            }
        }
    }
}

var handler = onVisibilityChange(el, function() {
    /* Your code go here */
});


// jQuery
$(window).on('DOMContentLoaded load resize scroll', handler);

/* // Non-jQuery
if (window.addEventListener) {
    addEventListener('DOMContentLoaded', handler, false);
    addEventListener('load', handler, false);
    addEventListener('scroll', handler, false);
    addEventListener('resize', handler, false);
} else if (window.attachEvent)  {
    attachEvent('onDOMContentLoaded', handler); // Internet Explorer 9+ :(
    attachEvent('onload', handler);
    attachEvent('onscroll', handler);
    attachEvent('onresize', handler);
}
*/

আপনি যদি কোনও ডিওএম পরিবর্তন করেন তবে তারা অবশ্যই আপনার উপাদানটির দৃশ্যমানতা পরিবর্তন করতে পারে।

নির্দেশিকা এবং সাধারণ সমস্যাগুলি:

হতে পারে আপনার পৃষ্ঠা জুম / মোবাইল ডিভাইস চিমটিটি ট্র্যাক করতে হবে? jQuery জুম / চিম্টি ক্রস ব্রাউজার হ্যান্ডেল করা উচিত , অন্যথায় প্রথম বা দ্বিতীয় লিঙ্কটি আপনাকে সহায়তা করা উচিত।

আপনি যদি ডিওএম সংশোধন করেন তবে এটি উপাদানটির দৃশ্যমানতাকে প্রভাবিত করতে পারে। আপনার এটি নিয়ন্ত্রণ করা উচিত এবং handler()ম্যানুয়ালি কল করা উচিত। দুর্ভাগ্যক্রমে, আমাদের কোনও ক্রস ব্রাউজার নেইonrepaint ইভেন্ট নেই। অন্যদিকে যা আমাদের অনুকূলতা তৈরি করতে এবং কেবলমাত্র ডিওএম পরিবর্তনগুলিতে পুনরায় চেক করার অনুমতি দেয় যা কোনও উপাদানের দৃশ্যমানতা পরিবর্তন করতে পারে।

এটি কখনই jQuery inside (ডকুমেন্ট) এর অভ্যন্তরে ব্যবহার করবেন না only কেবলমাত্র প্রস্তুত () , কারণ কোনও ওয়ারেন্টি নেই সিএসএস প্রয়োগ করা হয়েছে এই মুহূর্তে। আপনার কোডটি একটি হার্ড ড্রাইভে আপনার সিএসএসের সাথে স্থানীয়ভাবে কাজ করতে পারে তবে একবার দূরবর্তী সার্ভারে রাখলে এটি ব্যর্থ হবে।

DOMContentLoadedবরখাস্ত করার পরে , শৈলী প্রয়োগ করা হয় , তবে চিত্রগুলি এখনও লোড হয়নি । সুতরাং, আমাদের window.onloadইভেন্ট শ্রোতা যুক্ত করা উচিত ।

আমরা এখনও জুম / পিঞ্চ ইভেন্টটি ধরতে পারি না।

শেষ অবলম্বন নিম্নলিখিত কোড হতে পারে:

/* TODO: this looks like a very bad code */
setInterval(handler, 600);

আপনি দুর্দান্ত বৈশিষ্ট্য পৃষ্ঠাটি ব্যবহার করতে পারেন ভিসিবিলি যদি আপনার ওয়েব পৃষ্ঠার সাথে থাকা ট্যাবটি সক্রিয় এবং দৃশ্যমান হয় তবে যত্নশীল যদি আপনি HTML5 API এর ।

টোডো: এই পদ্ধতিটি দুটি পরিস্থিতিতে পরিচালনা করে না:


6
আমি এই সমাধানটি ব্যবহার করছি (যদিও "বটম" টাইপো থেকে সাবধান থাকুন)। সচেতন হওয়ার মতো কিছু বিষয় রয়েছে, যখন আমরা যে উপাদানটি বিবেচনা করছি তার মধ্যে চিত্র থাকবে। সীমানার আয়তক্ষেত্রটির সঠিক মান পেতে Chrome কে লোড করার জন্য অপেক্ষা করতে হবে। মনে হচ্ছে ফায়ারফক্সের এই "সমস্যা" নেই
ক্লাদিও

4
আপনি যখন দেহের অভ্যন্তরে কোনও ধারকটিতে স্ক্রোলিং সক্ষম করে থাকেন তখন এটি কাজ করে? উদাহরণস্বরূপ এটি এখানে কাজ করে না - agaase.github.io/webpages/demo/isonscreen2.html isuleInViewport (document.getElementById ("innerele"))। ইনারেলে একটি ধারকটির ভিতরে উপস্থিত রয়েছে যা স্ক্রোলিং সক্ষম করেছে।
আগাছে

70
গণনাগুলি ধরে নেয় যে উপাদানটি স্ক্রিনের চেয়ে ছোট smaller আপনার যদি উচ্চ বা প্রশস্ত উপাদান থাকে তবে এটি ব্যবহার করা আরও সঠিক হতে পারেreturn (rect.bottom >= 0 && rect.right >= 0 && rect.top <= (window.innerHeight || document.documentElement.clientHeight) && rect.left <= (window.innerWidth || document.documentElement.clientWidth));
রোওনান

11
টিপ: যারা jQuery দিয়ে এটি বাস্তবায়নের চেষ্টা করছেন তাদের কাছে, এইচটিএমএল ডিওএম অবজেক্টে (যেমন, isElementInViewport(document.getElementById('elem'))) নয় এবং jQuery অবজেক্ট (যেমন, isElementInViewport($("#elem))) নয় কেবল একটি বন্ধুত্বপূর্ণ অনুস্মারক । JQuery এর সমতুল্য যোগ হয় [0]যেমন: isElementInViewport($("#elem)[0])
জিমিনি

11
el is not defined
এম_ওয়িলিট

175

হালনাগাদ

আধুনিক ব্রাউজারগুলিতে, আপনি অন্তর্ভুক্তি পর্যবেক্ষক API টি যাচাই করতে চান যা নীচের সুবিধাগুলি সরবরাহ করে:

  • স্ক্রোল ইভেন্ট শোনার চেয়ে ভাল পারফরম্যান্স
  • ক্রস ডোমেন iframes এ কাজ করে
  • কোনও উপাদান অন্যকে ছেদ করছে / ছেদ করছে কিনা তা বলতে পারে

ছেদটি পর্যবেক্ষক পুরোপুরি মানসম্পন্ন হওয়ার পথে এবং ইতোমধ্যে ক্রোম 51+, এজ 15+ এবং ফায়ারফক্স 55+ এ সমর্থিত এবং সাফারিটির জন্য বিকাশাধীন। একটি পলিফিলও পাওয়া যায়।


পূর্ববর্তী উত্তর

ড্যানের দেওয়া উত্তরের সাথে কিছু সমস্যা রয়েছে যা এটি কিছু পরিস্থিতিতে অনুপযুক্ত দৃষ্টিভঙ্গি তৈরি করতে পারে। এর কয়েকটি নীচের দিকে তার উত্তরে উল্লেখ করা হয়েছে যে তার কোডটি এমন উপাদানগুলির জন্য মিথ্যা ইতিবাচক প্রতিক্রিয়া দেবে:

  • পরীক্ষা করা হচ্ছে এমনটির সামনে অন্য একটি উপাদান দ্বারা লুকানো
  • পিতামাতা বা পূর্বপুরুষের উপাদানের দৃশ্যমান ক্ষেত্রের বাইরে
  • সিএসএস clipসম্পত্তি ব্যবহার করে একটি উপাদান বা তার শিশুদের লুকানো

এই সীমাবদ্ধতাগুলি একটি সাধারণ পরীক্ষার নিম্নলিখিত ফলাফলগুলিতে প্রদর্শিত হয় :

আইলেমেন্টইনভিউপোর্টটি ব্যবহার করে পরীক্ষা ব্যর্থ হয়েছে

সমাধান: isElementVisible()

নীচে পরীক্ষার ফলাফল এবং কোডের কিছু অংশের ব্যাখ্যা সহ সেই সমস্যাগুলির সমাধান এখানে Here

function isElementVisible(el) {
    var rect     = el.getBoundingClientRect(),
        vWidth   = window.innerWidth || document.documentElement.clientWidth,
        vHeight  = window.innerHeight || document.documentElement.clientHeight,
        efp      = function (x, y) { return document.elementFromPoint(x, y) };     

    // Return false if it's not in the viewport
    if (rect.right < 0 || rect.bottom < 0 
            || rect.left > vWidth || rect.top > vHeight)
        return false;

    // Return true if any of its four corners are visible
    return (
          el.contains(efp(rect.left,  rect.top))
      ||  el.contains(efp(rect.right, rect.top))
      ||  el.contains(efp(rect.right, rect.bottom))
      ||  el.contains(efp(rect.left,  rect.bottom))
    );
}

পরীক্ষায় উত্তীর্ণ: http://jsfiddle.net/AndyE/cAY8c/

এবং ফলাফল:

পরীক্ষায় উত্তীর্ণ হয়েছে, আইলেমেটভিজিবল ব্যবহার করে

অতিরিক্ত নোট

এই পদ্ধতিটি অবশ্য নিজস্ব সীমাবদ্ধতা ছাড়াই নয়। উদাহরণস্বরূপ, একই স্থানে থাকা অন্য উপাদানের তুলনায় নিম্ন জেড-ইনডেক্সের সাথে পরীক্ষিত কোনও উপাদানটি গোপন হিসাবে চিহ্নিত হবে এমনকি সামনের উপাদানটি এর কোনও অংশ লুকায় না। তবুও, ড্যানের সমাধানটি কভার করে না এমন কিছু ক্ষেত্রে এই পদ্ধতির ব্যবহার রয়েছে।

উভয়ই element.getBoundingClientRect()এবং document.elementFromPoint()সিএসএসওএম ওয়ার্কিং ড্রাফ্ট স্পেসিফিকেশনের অংশ এবং কমপক্ষে IE 6 এবং তারপরে এবং বেশিরভাগ ডেস্কটপ ব্রাউজারগুলিতে দীর্ঘ সময়ের জন্য সমর্থিত (তবে পুরোপুরি নয়)। এই ফাংশনগুলির উপর Quirksmode দেখুনআরও তথ্যের জন্য ।

contains()যে উপাদানটি ফেরত দিয়েছিল document.elementFromPoint()তা হ'ল উপাদানটির চাইল্ড নোড, যা আমরা দৃশ্যমানতার জন্য পরীক্ষা করছি to ফিরে আসা উপাদানটি একই উপাদান হলে এটি সত্যও ফিরে আসে। এটি চেকটিকে আরও শক্তিশালী করে তোলে। এটি সমস্ত বড় ব্রাউজারগুলিতে সমর্থিত, ফায়ারফক্স 9.0 এটিকে যুক্ত করা তাদের মধ্যে শেষ। পুরানো ফায়ারফক্স সমর্থনের জন্য, এই উত্তরের ইতিহাস পরীক্ষা করুন।

আপনি যদি দৃশ্যমানতার জন্য উপাদানটির চারপাশে আরও বেশি পয়েন্ট পরীক্ষা করতে চান - যেমন, উপাদানটি এর চেয়ে বেশি আচ্ছাদিত না হয়েছে তা নিশ্চিত করার জন্য, বলুন, 50% - উত্তরের শেষ অংশটি সামঞ্জস্য করতে খুব বেশি লাগবে না। তবে, সচেতন হন যে আপনি যদি 100 পিক্সেলটি দৃশ্যমান তা নিশ্চিত করার জন্য প্রতিটি পিক্সেলটি পরীক্ষা করেন তবে এটি সম্ভবত খুব ধীর হবে।


2
আপনি ডক.ডোকমেন্ট এলিমেন্ট.ক্লিয়েন্টউইথ ব্যবহার করার অর্থ দিয়েছিলেন? তার বদলে কি 'ডকুমেন্ট.ডোকমেন্ট এলেমেন্ট' হওয়া উচিত? একটি ভিন্ন নোট অন, এই শুধুমাত্র পদ্ধতি এছাড়াও ব্যবহারের জন্য একটি উপাদান বিষয়বস্তু গোপন css 'ক্লিপ' সম্পত্তি ব্যবহার করার মত ব্যবহারের ক্ষেত্রে জন্য কাজ করে: snook.ca/archives/html_and_css/hiding-content-for-accessibility
কেভিন

@ ক্ল্যাম্পিং: ভাল ক্যাচ, ধন্যবাদ আমি এটিকে আমার কোডের বাইরেই অনুলিপি করেছিলাম যেখানে আমি docএকটি উপন্যাস হিসাবে ব্যবহার করছি document। হ্যাঁ, আমি এটিকে প্রান্তের ক্ষেত্রে একটি শালীন সমাধান হিসাবে ভাবতে চাই।
অ্যান্ডি ই

2
আমার জন্য এটি কাজ করছে না। তবে পূর্বের উত্তরে ইনভিউপোর্ট () এফএফ-এ কাজ করছে।
সত্য প্রকাশ

9
সীমানা কোণগুলি প্রত্যাশিত উপাদানটি ফিরে না আসতে পারে কারণ আপনি গোলাকার কোণগুলি বা কোনও রূপান্তর প্রয়োগ করেছেন তবে উপাদানটির কেন্দ্রটি দৃশ্যমান কিনা তা পরীক্ষা করে নেওয়া উপকারী হতে পারে:element.contains(efp(rect.right - (rect.width / 2), rect.bottom - (rect.height / 2)))
জারেড

2
আমার জন্য ইনপুটগুলিতে কাজ করেনি (ক্রোম ক্যানারি 50)। নিশ্চিত না কেন, সম্ভবত দেশীয় রাউন্ডার কোণে? এটির কাজ করার জন্য আমাকে কর্ডগুলি সামান্য হ্রাস করতে হয়েছিল (efp (rect.left + 1, rect.top + 1)) || el.contains (efp (rect.right-1, rect.top + 1)) || el.contains (efp (rect.right-1, rect.bottom-1)) || el.contains (efp (rect.left + 1, rect.bottom-1))
রায়জ্যাক্স

65

আমি ড্যান এর উত্তর চেষ্টা করেছিলাম । তবে সীমা নির্ধারণ করতে ব্যবহৃত বীজগণিতের অর্থ হল যে উপাদানটি উভয়ই হওয়া উচিত get ভিউপোর্টের আকার এবং সম্পূর্ণরূপে ভিউপোর্টের অভ্যন্তরে থাকা true, সহজেই মিথ্যা নেতিবাচক দিকে পরিচালিত করে। যদি আপনি নির্ধারণ করতে চান যে কোনও উপাদান আদৌ ভিউপোর্টে রয়েছে কিনা, রাইভের উত্তরটি নিকটে, তবে যে উপাদানটির পরীক্ষা করা হচ্ছে তা ভিউপোর্টকে ওভারল্যাপ করা উচিত, তাই এটি চেষ্টা করুন:

function isElementInViewport(el) {
    var rect = el.getBoundingClientRect();

    return rect.bottom > 0 &&
        rect.right > 0 &&
        rect.left < (window.innerWidth || document.documentElement.clientWidth) /* or $(window).width() */ &&
        rect.top < (window.innerHeight || document.documentElement.clientHeight) /* or $(window).height() */;
}

33

পাবলিক সার্ভিস হিসাবে:
সঠিক গণনার সাথে ড্যানের উত্তর (উপাদানটি> উইন্ডো হতে পারে, বিশেষত মোবাইল ফোনের স্ক্রিনে) এবং সঠিক জিকুয়েরি পরীক্ষার পাশাপাশি ইলেক্ট পার্টিশনালইন ভিউপোর্টটি যুক্ত করে:

উপায় দ্বারা, পার্থক্য window.innerWidth এবং document.documentElement.clientWidth মধ্যে যে clientWidth / clientHeight, স্ক্রলবার অন্তর্ভুক্ত নয় যখন window.innerWidth / উচ্চতা নেই।

function isElementPartiallyInViewport(el)
{
    // Special bonus for those using jQuery
    if (typeof jQuery !== 'undefined' && el instanceof jQuery) 
        el = el[0];

    var rect = el.getBoundingClientRect();
    // DOMRect { x: 8, y: 8, width: 100, height: 100, top: 8, right: 108, bottom: 108, left: 8 }
    var windowHeight = (window.innerHeight || document.documentElement.clientHeight);
    var windowWidth = (window.innerWidth || document.documentElement.clientWidth);

    // http://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap
    var vertInView = (rect.top <= windowHeight) && ((rect.top + rect.height) >= 0);
    var horInView = (rect.left <= windowWidth) && ((rect.left + rect.width) >= 0);

    return (vertInView && horInView);
}


// http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
function isElementInViewport (el)
{
    // Special bonus for those using jQuery
    if (typeof jQuery !== 'undefined' && el instanceof jQuery) 
        el = el[0];

    var rect = el.getBoundingClientRect();
    var windowHeight = (window.innerHeight || document.documentElement.clientHeight);
    var windowWidth = (window.innerWidth || document.documentElement.clientWidth);

    return (
           (rect.left >= 0)
        && (rect.top >= 0)
        && ((rect.left + rect.width) <= windowWidth)
        && ((rect.top + rect.height) <= windowHeight)
    );
}


function fnIsVis(ele)
{
    var inVpFull = isElementInViewport(ele);
    var inVpPartial = isElementPartiallyInViewport(ele);
    console.clear();
    console.log("Fully in viewport: " + inVpFull);
    console.log("Partially in viewport: " + inVpPartial);
}

পরীক্ষা ক্ষেত্রে

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
    <title>Test</title>
    <!--
    <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <script src="scrollMonitor.js"></script>
    -->

    <script type="text/javascript">

        function isElementPartiallyInViewport(el)
        {
            // Special bonus for those using jQuery
            if (typeof jQuery !== 'undefined' && el instanceof jQuery) 
                el = el[0];

            var rect = el.getBoundingClientRect();
            // DOMRect { x: 8, y: 8, width: 100, height: 100, top: 8, right: 108, bottom: 108, left: 8 }
            var windowHeight = (window.innerHeight || document.documentElement.clientHeight);
            var windowWidth = (window.innerWidth || document.documentElement.clientWidth);

            // http://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap
            var vertInView = (rect.top <= windowHeight) && ((rect.top + rect.height) >= 0);
            var horInView = (rect.left <= windowWidth) && ((rect.left + rect.width) >= 0);

            return (vertInView && horInView);
        }


        // http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
        function isElementInViewport (el)
        {
            // Special bonus for those using jQuery
            if (typeof jQuery !== 'undefined' && el instanceof jQuery) 
                el = el[0];

            var rect = el.getBoundingClientRect();
            var windowHeight = (window.innerHeight || document.documentElement.clientHeight);
            var windowWidth = (window.innerWidth || document.documentElement.clientWidth);

            return (
                   (rect.left >= 0)
                && (rect.top >= 0)
                && ((rect.left + rect.width) <= windowWidth)
                && ((rect.top + rect.height) <= windowHeight)
            );
        }


        function fnIsVis(ele)
        {
            var inVpFull = isElementInViewport(ele);
            var inVpPartial = isElementPartiallyInViewport(ele);
            console.clear();
            console.log("Fully in viewport: " + inVpFull);
            console.log("Partially in viewport: " + inVpPartial);
        }


        // var scrollLeft = (window.pageXOffset !== undefined) ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft,
        // var scrollTop = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
    </script>
</head>

<body>
    <div style="display: block; width: 2000px; height: 10000px; background-color: green;">

        <br /><br /><br /><br /><br /><br />
        <br /><br /><br /><br /><br /><br />
        <br /><br /><br /><br /><br /><br />

        <input type="button" onclick="fnIsVis(document.getElementById('myele'));" value="det" />

        <br /><br /><br /><br /><br /><br />
        <br /><br /><br /><br /><br /><br />
        <br /><br /><br /><br /><br /><br />

        <div style="background-color: crimson; display: inline-block; width: 800px; height: 500px;" ></div>
        <div id="myele" onclick="fnIsVis(this);" style="display: inline-block; width: 100px; height: 100px; background-color: hotpink;">
        t
        </div>

        <br /><br /><br /><br /><br /><br />
        <br /><br /><br /><br /><br /><br />
        <br /><br /><br /><br /><br /><br />

        <input type="button" onclick="fnIsVis(document.getElementById('myele'));" value="det" />
    </div>

    <!--
    <script type="text/javascript">

        var element = document.getElementById("myele");
        var watcher = scrollMonitor.create(element);

        watcher.lock();

        watcher.stateChange(function() {
            console.log("state changed");
            // $(element).toggleClass('fixed', this.isAboveViewport)
        });
    </script>
    -->
</body>
</html>

2
isElementPartiallyInViewportপাশাপাশি খুব দরকারী। সুন্দর.
আরজে কুথবার্টসন

আইলেমেন্টইনভিউপোর্ট (ঙ) এর জন্য: আপনার কোড চিত্রগুলিও লোড করছে না, এটি সঠিক: ফাংশনটি রয়েছে এলিমেটভিউপোর্ট (ঙ) {var t = e.getBoundingClientRect (); রিটার্ন t.top> = 0 && t.left> = 0 && t.bottom <= (window.innerHeight || ডকুমেন্ট.ডোকামেন্ট এলিমেন্ট.clientHeight) && t.right <= (উইন্ডো। }
অরুণ চৌহান

1
@ অরুন চৌহান: আমার কোডের কোনওটিই চিত্রগুলি লোড করছে না, তবে এটি কেন করা উচিত, এবং সূত্রটি সঠিক।
স্টিফান স্টেইগার

1
@ স্টারগামুন: কারণটি পুরানো ব্রাউজারগুলির সমর্থন।
স্টেফান স্টেইগার

1
এমডিএন অনুসারে @ স্টেফানস্টেইগার এটি আইই 9 এর পরে সমর্থিত তাই এটি ব্যবহারিকভাবে নিরাপদ (কমপক্ষে আমার ক্ষেত্রে) কেবল উইন্ডো.innerHeight সরাসরি ব্যবহার করতে। ধন্যবাদ!
তারগমন

28

উৎস দেখুন শেষপ্রান্তে , যা ব্যবহার getBoundingClientRect । এটা দেখতে:

function inViewport (el) {

    var r, html;
    if ( !el || 1 !== el.nodeType ) { return false; }
    html = document.documentElement;
    r = el.getBoundingClientRect();

    return ( !!r
      && r.bottom >= 0
      && r.right >= 0
      && r.top <= html.clientHeight
      && r.left <= html.clientWidth
    );

}

উপাদানটির কোনও অংশ ভিউপোর্টে trueথাকলে এটি ফিরে আসে ।


27

আমার সংক্ষিপ্ত এবং দ্রুত সংস্করণ:

function isElementOutViewport(el){
    var rect = el.getBoundingClientRect();
    return rect.bottom < 0 || rect.right < 0 || rect.left > window.innerWidth || rect.top > window.innerHeight;
}

এবং প্রয়োজন মতো একটি জেএসফিডাল: https://jsfiddle.net/on1g619L/1/


4
আমার সমাধানটি আরও লোভী এবং দ্রুত, যখন উপাদানটির ভিউপোর্টে কোনও পিক্সেল থাকে, এটি মিথ্যা ফিরে আসবে।
এরিক চেন

1
আমি এটা পছন্দ করি. সংক্ষিপ্ত। আপনি প্রথম লাইনে ফাংশন নাম এবং প্রথম বন্ধনী এবং বন্ধনী এবং বন্ধনী মধ্যে ফাঁকা স্থান অপসারণ করতে পারে। এই স্পেসগুলি কখনই পছন্দ করেনি। হতে পারে এটি কেবলমাত্র আমার পাঠ্য সম্পাদক এটি রঙিন কোডগুলি যা এখনও এটি পড়া সহজ করে তোলে। ফাংশন aaa (আরজি) {বিবরণ} আমি জানি যে এটি দ্রুত সম্পাদন করে না, পরিবর্তে ক্ষুদ্রতরকরণের আওতায় পড়ে।
YK

21

আমি এটা কষ্ট যে একটি ছিল না পাওয়া jQuery এর কার্যকারিতা উপলব্ধ -centric সংস্করণ। আমি যখন ড্যানের সমাধানটি পেলাম পেলাম ভাবীদের জন্য কিছু সরবরাহ করার সুযোগটি দেখেছি যারা jQuery ওও স্টাইলে প্রোগ্রাম করতে পছন্দ করে। এটি সুন্দর এবং চটজলদি এবং আমার জন্য কবজির মতো কাজ করে।

বাড়া বিং বাদা বুম

$.fn.inView = function(){
    if(!this.length) 
        return false;
    var rect = this.get(0).getBoundingClientRect();

    return (
        rect.top >= 0 &&
        rect.left >= 0 &&
        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
        rect.right <= (window.innerWidth || document.documentElement.clientWidth)
    );

};

// Additional examples for other use cases
// Is true false whether an array of elements are all in view
$.fn.allInView = function(){
    var all = [];
    this.forEach(function(){
        all.push( $(this).inView() );
    });
    return all.indexOf(false) === -1;
};

// Only the class elements in view
$('.some-class').filter(function(){
    return $(this).inView();
});

// Only the class elements not in view
$('.some-class').filter(function(){
    return !$(this).inView();
});

ব্যবহার

$(window).on('scroll',function(){

    if( $('footer').inView() ) {
        // Do cool stuff
    }
});

1
কোঁকড়া ধনুর্বন্ধনী যদি বিবৃতি বন্ধ করতে যথেষ্ট হবে?
calasyr

1
আমি এটি একটি অভিন্ন শ্রেণীর একাধিক উপাদান দিয়ে কাজ করতে পারি না।
হিজ অফ ওজ

1
@ দ্য হিজোফজ ওযে আপনি নিয়ে আসা অন্যান্য সম্ভাব্য ব্যবহারের মামলার উদাহরণ দিতে আমি আমার উত্তর আপডেট করেছি। শুভকামনা করছি.
r3wt

10

নতুন ছেদটি পর্যবেক্ষক এপিআই এই প্রশ্নটিকে খুব সরাসরি সম্বোধন করে।

এই সমাধানটির একটি পলিফিলের প্রয়োজন হবে কারণ সাফারি, অপেরা এবং ইন্টারনেট এক্সপ্লোরার এটি এখনও সমর্থন করে না (পলিফিলটি সমাধানটিতে অন্তর্ভুক্ত করা হয়েছে)।

এই সমাধানে, এমন একটি বাক্স আছে যা লক্ষ্যমাত্রা (পর্যবেক্ষণ) is এটি যখন নজরে আসে তখন শিরোনামের উপরের অংশের বোতামটি লুকানো থাকে। বাক্সটি প্রদর্শনটি ছেড়ে যাওয়ার পরে এটি প্রদর্শিত হয়।

const buttonToHide = document.querySelector('button');

const hideWhenBoxInView = new IntersectionObserver((entries) => {
  if (entries[0].intersectionRatio <= 0) { // If not in view
    buttonToHide.style.display = "inherit";
  } else {
    buttonToHide.style.display = "none";
  }
});

hideWhenBoxInView.observe(document.getElementById('box'));
header {
  position: fixed;
  top: 0;
  width: 100vw;
  height: 30px;
  background-color: lightgreen;
}

.wrapper {
  position: relative;
  margin-top: 600px;
}

#box {
  position: relative;
  left: 175px;
  width: 150px;
  height: 135px;
  background-color: lightblue;
  border: 2px solid;
}
<script src="https://polyfill.io/v2/polyfill.min.js?features=IntersectionObserver"></script>
<header>
  <button>NAVIGATION BUTTON TO HIDE</button>
</header>
  <div class="wrapper">
    <div id="box">
    </div>
  </div>


3
গুড বাস্তবায়ন, এবং লিংক অনুযায়ী এই উত্তরটি এটা করা উচিত যোগ করে সাফারি কাজ <!DOCTYPE html>HTML এ
alôn Eitan

দ্রষ্টব্য এটি IntersectionObserverএকটি পরীক্ষামূলক বৈশিষ্ট্য (যা ভবিষ্যতে পরিবর্তিত হতে পারে)।
কার্তিক চিন্তলা

2
@ কার্থিক চিন্তালা - এটি আইই ব্যতীত প্রতিটি ব্রাউজারে সমর্থিত - এবং একটি পলিফিলও উপলব্ধ।
র্যান্ডি ক্যাসবার্ন

কেবল পরিবর্তনগুলি সনাক্ত করে যেহেতু ওপি-র প্রশ্নের সমাধান করে না : IntersectionObserverমূলের তুলনায় লক্ষ্যমাত্রার চলাফেরার পরে কেবল কলব্যাক চালায়।
ব্র্যান্ডন হিল

observeইভেন্ট কল করার সময় অবিলম্বে আপনাকে ট্র্যাক করা উপাদানের বর্তমান চৌরাস্তা স্থিতি অবহিত করা হয়। সুতরাং, কোনও উপায়ে - এটি সম্বোধন করে।
মেসকালিতো

8

এখানে যে সমস্ত উত্তর আমি মুখোমুখি হয়েছি তা কেবলমাত্র বর্তমান ভিউপোর্টের অভ্যন্তরে উপাদানটি অবস্থান করে কিনা তা পরীক্ষা করে দেখুন । তবে এর অর্থ এই নয় যে এটি দৃশ্যমান
যদি প্রদত্ত উপাদানটি উপচে পড়া বিষয়বস্তু সহ কোনও ডিভের ভিতরে থাকে এবং এটি দেখার বাইরে স্ক্রোল হয় তবে কী হবে?

এটি সমাধান করার জন্য, আপনাকে পরীক্ষা করতে হবে যে উপাদানটি সমস্ত পিতামাতার অন্তর্ভুক্ত রয়েছে কিনা।
আমার সমাধান ঠিক এটি করে:

এটি আপনাকে উপাদানটির কতটা দৃশ্যমান হতে হবে তা নির্দিষ্ট করতে দেয়।

Element.prototype.isVisible = function(percentX, percentY){
    var tolerance = 0.01;   //needed because the rects returned by getBoundingClientRect provide the position up to 10 decimals
    if(percentX == null){
        percentX = 100;
    }
    if(percentY == null){
        percentY = 100;
    }

    var elementRect = this.getBoundingClientRect();
    var parentRects = [];
    var element = this;

    while(element.parentElement != null){
        parentRects.push(element.parentElement.getBoundingClientRect());
        element = element.parentElement;
    }

    var visibleInAllParents = parentRects.every(function(parentRect){
        var visiblePixelX = Math.min(elementRect.right, parentRect.right) - Math.max(elementRect.left, parentRect.left);
        var visiblePixelY = Math.min(elementRect.bottom, parentRect.bottom) - Math.max(elementRect.top, parentRect.top);
        var visiblePercentageX = visiblePixelX / elementRect.width * 100;
        var visiblePercentageY = visiblePixelY / elementRect.height * 100;
        return visiblePercentageX + tolerance > percentX && visiblePercentageY + tolerance > percentY;
    });
    return visibleInAllParents;
};

এই সমাধানটি এই বিষয়টিকে উপেক্ষা করেছে যে অন্যান্য তথ্যের কারণে উপাদানগুলি দৃশ্যমান নাও হতে পারে opacity: 0

আমি ক্রোম এবং ইন্টারনেট এক্সপ্লোরার 11 এ এই সমাধানটি পরীক্ষা করেছি।


8

আমি দেখতে পেয়েছি যে এখানে গৃহীত উত্তর বেশিরভাগ ব্যবহারের ক্ষেত্রে অত্যধিক জটিল। এই কোডটি কাজটি ভাল করে (jQuery ব্যবহার করে) এবং সম্পূর্ণভাবে দৃশ্যমান এবং আংশিকভাবে দৃশ্যমান উপাদানগুলির মধ্যে পার্থক্য করে:

var element         = $("#element");
var topOfElement    = element.offset().top;
var bottomOfElement = element.offset().top + element.outerHeight(true);
var $window         = $(window);

$window.bind('scroll', function() {

    var scrollTopPosition   = $window.scrollTop()+$window.height();
    var windowScrollTop     = $window.scrollTop()

    if (windowScrollTop > topOfElement && windowScrollTop < bottomOfElement) {
        // Element is partially visible (above viewable area)
        console.log("Element is partially visible (above viewable area)");

    } else if (windowScrollTop > bottomOfElement && windowScrollTop > topOfElement) {
        // Element is hidden (above viewable area)
        console.log("Element is hidden (above viewable area)");

    } else if (scrollTopPosition < topOfElement && scrollTopPosition < bottomOfElement) {
        // Element is hidden (below viewable area)
        console.log("Element is hidden (below viewable area)");

    } else if (scrollTopPosition < bottomOfElement && scrollTopPosition > topOfElement) {
        // Element is partially visible (below viewable area)
        console.log("Element is partially visible (below viewable area)");

    } else {
        // Element is completely visible
        console.log("Element is completely visible");
    }
});

আপনার অবশ্যই $window = $(window)স্ক্রোল হ্যান্ডলারের বাইরে ক্যাশে করা উচিত ।
স্যাম

4

Element.getBoundingClientRect () এর সমর্থন হিসাবে সহজ সমাধানটি নিখুঁত হয়ে গেছে :

function isInView(el) {
    let box = el.getBoundingClientRect();
    return box.top < window.innerHeight && box.bottom >= 0;
}

এটি কীভাবে মোবাইল ব্রাউজারগুলিতে আচরণ করে? তাদের বেশিরভাগ ভিউপোর্ট সম্পর্কিত বগি, তাদের শিরোনামটি স্ক্রোলটিতে উপরে বা নীচে যায় এবং কীবোর্ডটি প্রদর্শিত হয় যখন এটি অ্যান্ড্রয়েড বা আইওএস ইত্যাদির উপর নির্ভর করে বিভিন্ন আচরণ করে
কেভ

@ কেভকে আপনি যখন এই পদ্ধতিটি কল করেন তার উপর নির্ভর করে ঠিক কাজ করা উচিত। যদি আপনি এটি কল করেন এবং উইন্ডোটির আকার পরিবর্তন করেন তবে ফলাফল সম্ভবত আর সঠিক হতে পারে না longer আপনি যে কার্যকারিতা চান তার উপর নির্ভর করে প্রতিটি আকার পরিবর্তন-ইভেন্টে আপনি এটি কল করতে পারেন। আপনার নির্দিষ্ট ব্যবহারের ক্ষেত্রে এবং আমাকে এখানে পিং করার বিষয়ে নির্দ্বিধায় জিজ্ঞাসা করুন।
একাকী

3

আমি মনে করি এটি এটি করার আরও কার্যকরী উপায়। ড্যানের উত্তর পুনরাবৃত্তির প্রসঙ্গে কাজ করে না।

এই উপাদানটি সমস্যার সমাধান করে যখন আপনার উপাদান অন্যদের মধ্যে থাকে তখন এইচটিএমএল ট্যাগ পর্যন্ত পুনরাবৃত্তিজনকভাবে কোনও স্তরের পরীক্ষা করে অন্যের স্ক্রোলযোগ্য ডিভগুলি থাকে এবং প্রথম মিথ্যাতে থামিয়ে দেয়।

/**
 * fullVisible=true only returns true if the all object rect is visible
 */
function isReallyVisible(el, fullVisible) {
    if ( el.tagName == "HTML" )
            return true;
    var parentRect=el.parentNode.getBoundingClientRect();
    var rect = arguments[2] || el.getBoundingClientRect();
    return (
            ( fullVisible ? rect.top    >= parentRect.top    : rect.bottom > parentRect.top ) &&
            ( fullVisible ? rect.left   >= parentRect.left   : rect.right  > parentRect.left ) &&
            ( fullVisible ? rect.bottom <= parentRect.bottom : rect.top    < parentRect.bottom ) &&
            ( fullVisible ? rect.right  <= parentRect.right  : rect.left   < parentRect.right ) &&
            isReallyVisible(el.parentNode, fullVisible, rect)
    );
};

3

অ্যান্ড্রয়েডে গুগল ক্রোম জুম করার সময় সর্বাধিক গৃহীত উত্তরগুলি কাজ করে না। অ্যান্ড্রয়েডে ক্রোমের জন্য অ্যাকাউন্টে ড্যানের উত্তরের সাথে মিশ্রণে ভিজ্যুয়ালভিউপোর্ট অবশ্যই ব্যবহার করা উচিত। নিম্নলিখিত উদাহরণটি কেবল উল্লম্ব চেকটি অ্যাকাউন্টে নেয় এবং উইন্ডো উচ্চতার জন্য jQuery ব্যবহার করে:

var Rect = YOUR_ELEMENT.getBoundingClientRect();
var ElTop = Rect.top, ElBottom = Rect.bottom;
var WindowHeight = $(window).height();
if(window.visualViewport) {
    ElTop -= window.visualViewport.offsetTop;
    ElBottom -= window.visualViewport.offsetTop;
    WindowHeight = window.visualViewport.height;
}
var WithinScreen = (ElTop >= 0 && ElBottom <= WindowHeight);

2

এখানে আমার সমাধান। কোনও স্ক্রোলযোগ্য ধারকের ভিতরে কোনও উপাদান লুকানো থাকলে এটি কাজ করবে।

এখানে একটি ডেমো রয়েছে (উইন্ডোটিকে আবার আকার দেওয়ার চেষ্টা করুন)

var visibleY = function(el){
    var top = el.getBoundingClientRect().top, rect, el = el.parentNode;
    do {
        rect = el.getBoundingClientRect();
        if (top <= rect.bottom === false)
            return false;
        el = el.parentNode;
    } while (el != document.body);
    // Check it's within the document viewport
    return top <= document.documentElement.clientHeight;
};

আমার কেবল এটি ওয়াই অক্ষে দৃশ্যমান কিনা তা পরীক্ষা করে দেখার দরকার ছিল (একটি স্ক্রোলিং এজ্যাক্স লোড-মোর-রেকর্ড বৈশিষ্ট্যের জন্য)।


2

ড্যানের সমাধানের ভিত্তিতে , আমি বাস্তবায়নটি পরিষ্কার করতে গিয়েছিলাম যাতে এটি একই পৃষ্ঠায় একাধিকবার ব্যবহার করা সহজ হয়:

$(function() {

  $(window).on('load resize scroll', function() {
    addClassToElementInViewport($('.bug-icon'), 'animate-bug-icon');
    addClassToElementInViewport($('.another-thing'), 'animate-thing');
    // 👏 repeat as needed ...
  });

  function addClassToElementInViewport(element, newClass) {
    if (inViewport(element)) {
      element.addClass(newClass);
    }
  }

  function inViewport(element) {
    if (typeof jQuery === "function" && element instanceof jQuery) {
      element = element[0];
    }
    var elementBounds = element.getBoundingClientRect();
    return (
      elementBounds.top >= 0 &&
      elementBounds.left >= 0 &&
      elementBounds.bottom <= $(window).height() &&
      elementBounds.right <= $(window).width()
    );
  }

});

আমি যেভাবে এটি ব্যবহার করছি তা হ'ল উপাদানটি যখন দেখায় স্ক্রোল করে, তখন আমি একটি ক্লাস যুক্ত করছি যা একটি সিএসএস কীফ্রেম অ্যানিমেশনটি ট্রিগার করে। এটি বেশ সোজা এবং বিশেষত ভাল কাজ করে যখন আপনি কোনও পৃষ্ঠায় শর্তসাপেক্ষে সঞ্জীবিত করতে 10+ জিনিস পছন্দ করেন।


আপনার অবশ্যই $window = $(window)স্ক্রোল হ্যান্ডলারের বাইরে ক্যাশে করা উচিত
অ্যাডাম রেহাল

2

পূর্ববর্তী উত্তরের বেশিরভাগ ব্যবহারগুলি এই পয়েন্টগুলিতে ব্যর্থ হচ্ছে:

-যখন কোনও উপাদানের কোনও পিক্সেল দৃশ্যমান হয় তবে " কোণে " নয়,

-যখন কোনও উপাদান ভিউপোর্টের চেয়ে বড় এবং কেন্দ্রিক হয় ,

- তাদের মধ্যে বেশিরভাগ কেবলমাত্র একটি দস্তাবেজ বা উইন্ডোর ভিতরে একক উপাদানের জন্য চেক করছেন ।

ঠিক আছে, এই সমস্ত সমস্যার জন্য আমি একটি সমাধান করেছি এবং এর পক্ষগুলি হ'ল:

- visibleযখন আপনি কোনও দিক থেকে কেবল একটি পিক্সেল দেখায় এবং কোনও কোণে না থেকে ফিরে আসতে পারেন ,

- visibleভিউপোর্টের চেয়ে বড় উপাদান থাকা অবস্থায় আপনি এখনও ফিরতে পারবেন ,

- parent elementআপনি আপনার চয়ন করতে পারেন বা আপনি স্বয়ংক্রিয়ভাবে এটি চয়ন করতে পারেন,

উপর -Works পরিবর্তনশীল যোগ উপাদান খুব।

যদি আপনি নীচের স্নিপেটগুলি পরীক্ষা করে দেখেন যে overflow-scrollআপনি এলিমেন্টের ধারক ব্যবহারের ক্ষেত্রে পার্থক্য দেখবেন তাতে কোনও সমস্যা হবে না এবং দেখুন যে এখানে অন্যান্য উত্তরগুলির বিপরীতে পিক্সেলটি কোনও দিক থেকে প্রদর্শিত হয় বা যখন কোনও উপাদান ভিউপোর্টের চেয়ে বড় হয় এবং আমরা অভ্যন্তরীণ দেখতে পাচ্ছি এটি এখনও কাজ করে এমন উপাদানটির পিক্সেল

ব্যবহার সহজ:

// For checking element visibility from any sides
isVisible(element)

// For checking elements visibility in a parent you would like to check
var parent = document; // Assuming you check if 'element' inside 'document'
isVisible(element, parent)

// For checking elements visibility even if it's bigger than viewport
isVisible(element, null, true) // Without parent choice
isVisible(element, parent, true) // With parent choice

একটি বিক্ষোভের ছাড়া crossSearchAlgorithmযা দেখতে ভিউপোর্ট চেক element3 ভেতরের পিক্সেলের থেকে বড় উপাদানের জন্য দরকারী হল:

আপনি দেখুন, আপনি এলিমেন্ট 3 এর ভিতরে থাকা অবস্থায় এটি দৃশ্যমান কিনা তা জানাতে ব্যর্থ হয়, কারণ আমরা কেবল এটিই পরীক্ষা করে নিচ্ছি যে উপাদানটি পাশ বা কোণ থেকে দৃশ্যমান কিনা ।

এবং এটিতে অন্তর্ভুক্ত রয়েছে crossSearchAlgorithmযা visibleভিউপোর্টের চেয়ে উপাদানটি বড় হলে আপনাকে এখনও ফিরে আসতে দেয় :

জেএসফিডেল এর সাথে খেলবেন: http://jsfiddle.net/BerkerYuceer/grk5az2c/

এই কোডটি আরও সুনির্দিষ্ট তথ্যের জন্য তৈরি করা হয়েছে যদি উপাদানটির কোনও অংশ ভিউতে প্রদর্শিত হয় বা না থাকে। পারফরম্যান্স বিকল্প বা কেবল উল্লম্ব স্লাইডগুলির জন্য, এটি ব্যবহার করবেন না! এই কোডটি অঙ্কনের ক্ষেত্রে আরও কার্যকর।


1

একটি ভাল সমাধান:

function getViewportSize(w) {
    var w = w || window;
    if(w.innerWidth != null)
        return {w:w.innerWidth, h:w.innerHeight};
    var d = w.document;
    if (document.compatMode == "CSS1Compat") {
        return {
            w: d.documentElement.clientWidth,
            h: d.documentElement.clientHeight
        };
    }
    return { w: d.body.clientWidth, h: d.body.clientWidth };
}


function isViewportVisible(e) {
    var box = e.getBoundingClientRect();
    var height = box.height || (box.bottom - box.top);
    var width = box.width || (box.right - box.left);
    var viewport = getViewportSize();
    if(!height || !width)
        return false;
    if(box.top > viewport.h || box.bottom < 0)
        return false;
    if(box.right < 0 || box.left > viewport.w)
        return false;
    return true;
}

12
আপনার চেষ্টা করা উচিত এবং ব্যাখ্যা করা উচিত কেন আপনার সংস্করণটি আরও ভাল। এটি যেমন দাঁড়িয়েছে, অন্য সমাধানগুলির মতো এটি কমবেশি একই দেখাচ্ছে looks
অ্যান্ডি ই

1
দুর্দান্ত সমাধানটির একটি বাক্স / স্ক্রোলকন্টেইনার রয়েছে এবং উইন্ডো ব্যবহার করছে না (কেবল যদি এটি নির্দিষ্ট না করা হয়)। কোডটি আরও একটি সার্বজনীন সমাধান হিসাবে তুলনায় একবার দেখুন (এটি অনেক সন্ধান
করছিল

1

এটি যতটা সহজ পেতে পারে, আইএমও:

function isVisible(elem) {
  var coords = elem.getBoundingClientRect();
  return Math.abs(coords.top) <= coords.height;
}

0

এখানে একটি ফাংশন যে যদি একটি উপাদান একটি বর্তমান ভিউপোর্ট দৃশ্যমান হয় বলে হয় পিতা বা মাতা উপাদান:

function inParentViewport(el, pa) {
    if (typeof jQuery === "function"){
        if (el instanceof jQuery)
            el = el[0];
        if (pa instanceof jQuery)
            pa = pa[0];
    }

    var e = el.getBoundingClientRect();
    var p = pa.getBoundingClientRect();

    return (
        e.bottom >= p.top &&
        e.right >= p.left &&
        e.top <= p.bottom &&
        e.left <= p.right
    );
}

0

কোনও উপাদান কমপক্ষে আংশিকভাবে দেখার ক্ষেত্রে (উলম্ব দিক) এটি পরীক্ষা করে:

function inView(element) {
    var box = element.getBoundingClientRect();
    return inViewBox(box);
}

function inViewBox(box) {
    return ((box.bottom < 0) || (box.top > getWindowSize().h)) ? false : true;
}


function getWindowSize() {
    return { w: document.body.offsetWidth || document.documentElement.offsetWidth || window.innerWidth, h: document.body.offsetHeight || document.documentElement.offsetHeight || window.innerHeight}
}

0

আমি একই প্রশ্নটি পেয়েছিলাম এবং getBoundingClientRect () ব্যবহার করে এটি বের করেছিলাম।

এই কোডটি সম্পূর্ণ 'জেনেরিক' এবং এটি কাজ করার জন্য কেবল একবার লিখতে হবে (আপনি যে প্রতিটি উপাদানটি জানতে চান সেটি ভিউপোর্টে রয়েছে এটির জন্য আপনাকে এটি লিখতে হবে না)।

এই কোডটি কেবল ভোপপোর্টে অনুভূমিকভাবে নয় কিনা তা খতিয়ে দেখেছে see । এই ক্ষেত্রে, ভেরিয়েবল (অ্যারে) 'উপাদানগুলি' ভিউপোর্টে উল্লম্বভাবে যাচাই করার জন্য সমস্ত উপাদানগুলিকে ধারণ করে, সুতরাং আপনি যে কোনও উপাদান চাইলে ধরে নিন এবং সেগুলিকে সেখানে সংরক্ষণ করুন।

'লুপের জন্য', প্রতিটি উপাদান দিয়ে লুপ করে এবং ভিউপোর্টে এটি উল্লম্বভাবে রয়েছে কিনা তা পরীক্ষা করে। এই কোডটি ব্যবহারকারী প্রতিটি সময় স্ক্রোল কার্যকর করে! যদি getBoudingClientRect ()। শীর্ষটি ভিউপোর্টের 3/4 এর চেয়ে কম হয় (উপাদানটি ভিউপোর্টের এক চতুর্থাংশ), এটি 'ভিউপোর্টে' হিসাবে নিবন্ধিত হয়।

কোডটি জেনেরিক হওয়ায় আপনি ভিউপোর্টে 'কোন' উপাদানটি জানতে চান। এটি সন্ধান করার জন্য, আপনি এটি কাস্টম বৈশিষ্ট্য, নোডের নাম, আইডি, শ্রেণীর নাম এবং আরও অনেক কিছু দ্বারা নির্ধারণ করতে পারেন।

এখানে আমার কোড (এটি যদি কাজ না করে তবে আমাকে বলুন; এটি ইন্টারনেট এক্সপ্লোরার 11, ফায়ারফক্স 40.0.3, ক্রোম সংস্করণ 45.0.2454.85 মি, অপেরা 31.0.1889.174, এবং উইন্ডোজ 10 সহ এজতে পরীক্ষা করা হয়েছে, [এখনও সাফারি নয় ]) ...

// Scrolling handlers...
window.onscroll = function(){
  var elements = document.getElementById('whatever').getElementsByClassName('whatever');
  for(var i = 0; i != elements.length; i++)
  {
   if(elements[i].getBoundingClientRect().top <= window.innerHeight*0.75 &&
      elements[i].getBoundingClientRect().top > 0)
   {
      console.log(elements[i].nodeName + ' ' +
                  elements[i].className + ' ' +
                  elements[i].id +
                  ' is in the viewport; proceed with whatever code you want to do here.');
   }
};

0

এটি আমার জন্য সহজ এবং ছোট সমাধানটি কাজ করেছে।

উদাহরণ : আপনি দেখতে চান যে মৌলিক উপাদানটিতে ওভারফ্লো স্ক্রোল রয়েছে has

$(window).on('scroll', function () {

     var container = $('#sidebar');
     var containerHeight = container.height();
     var scrollPosition = $('#row1').offset().top - container.offset().top;

     if (containerHeight < scrollPosition) {
         console.log('not visible');
     } else {
         console.log('visible');
     }
})

0

এখানে সমস্ত উত্তর নির্ধারণ করছে যে উপাদানটি কোনও উপায়ে দৃশ্যমান নয়, ভিউপোর্টের মধ্যে সম্পূর্ণরূপে অন্তর্ভুক্ত রয়েছে কিনা। উদাহরণস্বরূপ, যদি কোনও চিত্রের অর্ধেক অংশ কেবল নীচের অংশে দৃশ্যমান হয় তবে "সমাধানগুলি" বিবেচনা করে সমাধানগুলি এখানে ব্যর্থ হবে।

আমার ব্যবহারের ক্ষেত্রে আমি যেখানে অলস লোডিং করছি সেখানে IntersectionObserverপপ-ইন চলাকালীন অ্যানিমেশনগুলির কারণে আমি ইতিমধ্যে পৃষ্ঠা লোডে ছেদকৃত কোনও চিত্র পর্যবেক্ষণ করতে চাইনি । এটি করতে, আমি নিম্নলিখিত কোডটি ব্যবহার করেছি:

const bounding = el.getBoundingClientRect();
const isVisible = (0 < bounding.top && bounding.top < (window.innerHeight || document.documentElement.clientHeight)) ||
        (0 < bounding.bottom && bounding.bottom < (window.innerHeight || document.documentElement.clientHeight));

এটি মূলত উপরে বা নীচের দিকের বাউন্ডটি ভিউপোর্টে স্বতন্ত্রভাবে রয়েছে কিনা তা দেখার জন্য এটি পরীক্ষা করছে। বিপরীত প্রান্তটি বাইরে থাকতে পারে তবে যতক্ষণ এক প্রান্তটি থাকবে ততক্ষণ এটি অন্তত আংশিকভাবে "দৃশ্যমান"।


-1

আমি এই ফাংশনটি ব্যবহার করি (বেশিরভাগ সময় x এর প্রয়োজন হয় না বলে এটি যদি y স্ক্রিন হয় তবে এটি পরীক্ষা করে)

function elementInViewport(el) {
    var elinfo = {
        "top":el.offsetTop,
        "height":el.offsetHeight,
    };

    if (elinfo.top + elinfo.height < window.pageYOffset || elinfo.top > window.pageYOffset + window.innerHeight) {
        return false;
    } else {
        return true;
    }

}

-3

অনুরূপ চ্যালেঞ্জের জন্য, আমি সত্যিই এই টুকরোটি উপভোগ করেছি যা স্ক্রোলইন্টোভিউআইফনিডেড () এর জন্য একটি পলিফিল উন্মোচিত করে ।

উত্তর দেওয়ার জন্য প্রয়োজনীয় সমস্ত কুংফু এই ব্লকের মধ্যে রয়েছে:

var parent = this.parentNode,
    parentComputedStyle = window.getComputedStyle(parent, null),
    parentBorderTopWidth = parseInt(parentComputedStyle.getPropertyValue('border-top-width')),
    parentBorderLeftWidth = parseInt(parentComputedStyle.getPropertyValue('border-left-width')),
    overTop = this.offsetTop - parent.offsetTop < parent.scrollTop,
    overBottom = (this.offsetTop - parent.offsetTop + this.clientHeight - parentBorderTopWidth) > (parent.scrollTop + parent.clientHeight),
    overLeft = this.offsetLeft - parent.offsetLeft < parent.scrollLeft,
    overRight = (this.offsetLeft - parent.offsetLeft + this.clientWidth - parentBorderLeftWidth) > (parent.scrollLeft + parent.clientWidth),
    alignWithTop = overTop && !overBottom;

thisআপনি যে উপাদানটি জানতে চান তা বোঝায় উদাহরণস্বরূপ, overTopবা overBottom- আপনার কেবল ড্রিফ্টটি পাওয়া উচিত ...

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.