ইভেন্ট শ্রোতা যখন উপাদানটি দৃশ্যমান হয়?


113

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

ধন্যবাদ


এই উত্তর সাহায্য করে? stackoverflow.com/questions/1397251/...
kangax

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

জাভাস্ক্রিপ্টে "অনভিজ্ঞ" ইভেন্টটি বাস্তবায়নের জন্য এই উত্তরটি দেখুন: stackoverflow.com/a/3807340/975097
অ্যান্ডারসন গ্রিন


এই দয়া করে দেখতে পারে। stackoverflow.com/questions/45429746/…
মার্টিন

উত্তর:


8

জাভাস্ক্রিপ্ট ইভেন্টগুলি ব্যবহারকারী কথোপকথনের সাথে মোকাবিলা করে , যদি আপনার কোডটি যথেষ্ট পরিমাণে সংগঠিত হয় তবে আপনার দৃশ্যমানতার বদলে একই জায়গায় আরম্ভের ফাংশনটি কল করতে সক্ষম হবেন (উদাহরণস্বরূপ, আপনাকে myElement.style.displayঅনেক জায়গায় পরিবর্তন করা উচিত নয় , পরিবর্তে, একটি ফাংশন / পদ্ধতি কল করুন যা এটি এবং অন্য কিছু আপনি চাইবেন)।


8
তবে আপনি কীভাবে দৃশ্যমানতার পরিবর্তনটি সনাক্ত করতে সক্ষম হবেন (যেমন কোনও উপাদান দৃশ্যমান হওয়ার সাথে সাথে কোনও ফাংশনকে কল করুন)?
অ্যান্ডারসন গ্রিন

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

6
আমি এই প্রশ্নটিকে অগ্রাহ্য করেছি কারণ এটি তৈরি করে সমস্ত বুদ্ধি থাকা সত্ত্বেও এটি আসল ইস্যু থেকে অপ্রাসঙ্গিক। (যদি আমি কোনও ফ্রেমে প্রদর্শন না করি তবে সমস্ত শিশু উপাদান অদৃশ্য হয়ে যায়)
সেবাস

2
@ সেবাস, বাচ্চাদের দৃশ্যমানতা এখানে কেন গুরুত্বপূর্ণ তা আমি সত্যিই বুঝতে পারি না। যাইহোক, যদি উত্তরটি আপনার ক্ষেত্রে নির্দিষ্ট ক্ষেত্রে (এটি যাই হোক না কেন) কার্যকর না হত তবে বেশিরভাগ প্রোগ্রামারদের জন্য একটি সমাধান (বা ব্যাখ্যা কেন সমাধান নেই কেন) তা নির্দেশ করে, তবে এটি এখনও আমার নম্র মতামতের একটি বৈধ উত্তর। আপনি যদি অন্য উত্তরগুলির মধ্যে আরও ভাল পছন্দ করেন (বিশেষত একটি যা পরবর্তী সময়ে তৈরি হয়েছিল, যখন প্রযুক্তির উন্নতি ঘটে এবং নতুন বিকল্পগুলি উপলভ্য হয়), আমি বিশ্বাস করি যে সঠিক উত্তরটি পরিবর্তনের জন্য একটি অনুরোধ ডাউনটাউটের চেয়ে আরও উপযুক্ত হবে। যাই হোক না কেন, মাথা উঁচু করে নেওয়ার জন্য ধন্যবাদ :)
মলতালেফ

2
@ ফিঘা, বাচ্চাদের নয়, তবে আপনি যে উপাদানটি দেখছেন সেটি যদি কোনও ফ্রেমে প্রদর্শিত হয় যা = কোনওটি নয়, আপনার কোনও চিহ্ন থাকতে পারে না।
সেবাস

66

এগিয়ে যেতে, নতুন এইচটিএমএল ছেদটি পর্যবেক্ষক এপিআই হ'ল আপনি যা খুঁজছেন তা। এটি আপনাকে কলব্যাক কনফিগার করতে দেয় যা ডাকা হয় যখনই একটি এলিমেন্ট, যাকে ডাকা হয় তাকে ডিভাইস ভিউপোর্ট বা নির্দিষ্ট উপাদানকে ছেদ করে। এটি ক্রোম, ফায়ারফক্স এবং এজের সর্বশেষতম সংস্করণগুলিতে উপলভ্য। আরও তথ্যের জন্য https://developer.mozilla.org/en-US/docs/Web/API/Intersication_Oserser_API দেখুন ।

প্রদর্শন পর্যবেক্ষণের জন্য সাধারণ কোড উদাহরণ: কিছুই স্যুইচিং নয়:

// Start observing visbility of element. On change, the
//   the callback is called with Boolean visibility as
//   argument:

respondToVisibility(element, callback) {
  var options = {
    root: document.documentElement
  }

  var observer = new IntersectionObserver((entries, observer) => {
    entries.forEach(entry => {
      callback(entry.intersectionRatio > 0);
    });
  }, options);

  observer.observe(element);
}

পদক্ষেপে: https://jsfiddle.net/elmarj/u35tez5n/5/


2
> ছেদটি পর্যবেক্ষক এপিআই আপনাকে কলব্যাক কনফিগার করতে দেয় যা ডাকা হয় যখনই একটি এলিমেন্টকে লক্ষ্য হিসাবে ডাকা হয়, এটি ডিভাইস ভিউপোর্ট বা নির্দিষ্ট উপাদানকে ছেদ করে;
stil

1
মনে রাখবেন যে ইন্টারঅ্যাকশনঅবার্সার এই মুহুর্তে সাফারিটিতে কাজ করে না। caniuse.com/#feat=intersicationobserver দেখে মনে হচ্ছে কোনও প্যাচ চলছে। bugs.webkit.org/show_bug.cgi?id=159475
মিকেল পিক

8
যখন এরকম শীতল কোনও কিছুর প্রতি IE এর সমর্থন না থাকায় আমাদের জীবন নষ্ট করা বন্ধ হয়ে যায় তখন?
পিটার মুর

5
@ পিটারমুর এটি সমর্থন করার চেষ্টা বন্ধ করার সাথে সাথেই। শুধু না।
জোনি কেন

4
হাঃ হাঃ হাঃ. কখনও কখনও এটি আমাদের সিদ্ধান্ত হয় না।
পিটার মুর

44
var targetNode = document.getElementById('elementId');
var observer = new MutationObserver(function(){
    if(targetNode.style.display != 'none'){
        // doSomething
    }
});
observer.observe(targetNode, { attributes: true, childList: true });

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


4
টার্গেটনোড প্রদর্শিত না হলে এটি কাজ করে না কারণ পূর্বপুরুষ প্রদর্শিত হয় না তবে প্রদর্শিত হয়।
মার্কো একস্টেইন

সম্মত! আমি এটি অন্য স্ট্যাকওভারফ্লো উত্তরে ব্যবহার করেছি: স্ট্যাকওভারফ্লো.
নিক টিমমার

দুর্ভাগ্যক্রমে, এটি কেবলমাত্র উপাদানটিতে ইনলাইন স্টাইলগুলি ব্যবহার করার সময় কাজ করে না, যখন পরিবর্তনটি সিএসএস-শ্রেণির পরিবর্তনের ফলাফল হিসাবে ঘটে (যা পূর্ববর্তী পরিস্থিতিতে আপনার ইতিমধ্যে সম্পূর্ণ অগ্রগতিমূলক নিয়ন্ত্রণ রয়েছে বলে প্রদত্ত যেটি সম্ভবত এটির বেশি সম্ভাবনা রয়েছে)। সমস্যাটি দেখায় এমন ফিডাল : jsfiddle.net/elmarj/uye62Lxc/4 । স্টাইল-পরিবর্তনগুলি কীভাবে পর্যবেক্ষণ করতে হবে তার আরও সম্পূর্ণ আলোচনার জন্য এখানে দেখুন: ডিভ টু
এলমার জানসেন ২

আসলে এখানে ব্যবহার করার জন্য সঠিক পর্যবেক্ষকটি হবেন IntersectionObserver- stackoverflow.com/a/52627221/2803743
kan

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

15

কমপক্ষে একটি উপায় আছে তবে এটি খুব ভাল উপায় নয়। আপনি কেবল এই জাতীয় পরিবর্তনের জন্য উপাদানটি পোল করতে পারেন:

var previous_style,
    poll = window.setInterval(function()
{
    var current_style = document.getElementById('target').style.display;
    if (previous_style != current_style) {
        alert('style changed');
        window.clearInterval(poll);
    } else {
        previous_style = current_style;
    }
}, 100);

ডিওএম স্ট্যান্ডার্ডটি মিউটেশন ইভেন্টগুলিও নির্দিষ্ট করে , তবে আমি সেগুলি ব্যবহারের সুযোগ পাই নি এবং তারা কতটা সমর্থিত তা আমি নিশ্চিত নই। আপনি এগুলি তাদের ব্যবহার করুন:

target.addEventListener('DOMAttrModified', function()
{
    if (e.attrName == 'style') {
        alert('style changed');
    }
}, false);

এই কোডটি আমার মাথার উপরের দিক থেকে বন্ধ, সুতরাং আমি নিশ্চিত না যে এটি কাজ করবে কিনা।

সবচেয়ে ভাল এবং সহজ সমাধান হ'ল আপনার টার্গেটটি প্রদর্শন করে ফাংশনে একটি কলব্যাক।


1
আকর্ষণীয়, আপনাকে ধন্যবাদ। কয়েক বছর পরে, DOMAttrModified এর স্থিতি পরিবর্তিত হয়েছে: "হ্রাস করা হয়েছে This ওয়েব বৈশিষ্ট্যগুলি থেকে এই বৈশিষ্ট্যটি সরানো হয়েছে some যদিও কিছু ব্রাউজার এখনও এটি সমর্থন করতে পারে, এটি বাদ দেওয়ার প্রক্রিয়াধীন।" (মজিলা)
বার্নিনলিও


14

আমার একই সমস্যা ছিল এবং এটি আমাদের সাইটের জন্য সমাধান করার জন্য একটি jQuery প্লাগইন তৈরি করেছি।

https://github.com/shaunbowe/jquery.visibilityChanged

আপনার উদাহরণের ভিত্তিতে আপনি এটি কীভাবে ব্যবহার করবেন তা এখানে:

$('#contentDiv').visibilityChanged(function(element, visible) {
    alert("do something");
});

4
এই সমাধানটি .is(':visible')পাশাপাশি ব্যবহার করে setTimeout
Hp93

7

@ ফিগা যেমন বলেছেন যে এটি যদি আপনার নিজস্ব ওয়েব পৃষ্ঠা হয় তবে উপাদানটি দৃশ্যমান করার পরে আপনাকে যা চালাতে হবে তা চালানো উচিত।

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

উদাহরণস্বরূপ, ডিওমে data-widgetযুক্ত হওয়ার কারণে অ্যাট্রিবিউট যুক্ত উপাদানগুলির জন্য একটি ইভেন্ট ট্রিগার করা । ঋণগ্রহণ ডেভিড ওয়ালশ এর ব্লগ থেকে এই চমৎকার উদাহরণ :

var observer = new MutationObserver(function(mutations) {
    // For the sake of...observation...let's output the mutation to console to see how this all works
    mutations.forEach(function(mutation) {
        console.log(mutation.type);
    });    
});

// Notify me of everything!
var observerConfig = {
    attributes: true, 
    childList: true, 
    characterData: true 
};

// Node, config
// In this case we'll listen to all changes to body and child nodes
var targetNode = document.body;
observer.observe(targetNode, observerConfig);

প্রত্যুত্তর অন্তর্ভুক্ত added, removed, valueChangedআরো এবং । ইত্যাদি valueChangedসহ সমস্ত বৈশিষ্ট্য অন্তর্ভুক্তdisplay


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

প্রশ্নের উত্তর দেয় না, এবং কেবল লিঙ্কগুলি পোস্ট করার পরামর্শ দেওয়া হয় না।
অ্যালেক্স হলসগ্রোভ

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

নোট করুন যে এটি এখনও সেই অংশটি জুড়েছে না যা ব্যাখ্যা করে যে রূপান্তর পর্যবেক্ষণ প্রক্রিয়া "দৃশ্যমানতা" কোথায় আসে
মাইক 'পোম্যাক্স' কামারম্যানস


3

কেবলমাত্র DOMAttr রূপান্তরিত ইভেন্ট শ্রোতাদের ব্রাউজার সমর্থন সম্পর্কে মন্তব্য করতে:

ক্রস ব্রাউজার সমর্থন

এই ইভেন্টগুলি বিভিন্ন ব্রাউজার জুড়ে ধারাবাহিকভাবে প্রয়োগ করা হয় না, উদাহরণস্বরূপ:

  • সংস্করণ 9 এর পূর্ববর্তী IE কোনওভাবে মিউটেশন ইভেন্টগুলিকে সমর্থন করে না এবং সেগুলির কয়েকটি সংস্করণ 9-তে সঠিকভাবে প্রয়োগ করে না (উদাহরণস্বরূপ, DOMNodeInsert)

  • ওয়েবকিট DOMAttrModified সমর্থন করে না (ওয়েবকিট বাগ 8191 এবং কর্মক্ষেত্র দেখুন)

  • "মিউটেশন নেম ইভেন্টগুলি", যেমন ডোমমেন্টমেন্ট নেম চেঞ্জড এবং ডিওএম্যাট্রিবিউটনেম চ্যাঞ্জড ফায়ারফক্সে সমর্থিত নয় (সংস্করণ 11 হিসাবে), এবং সম্ভবত অন্যান্য ব্রাউজারগুলিতেও।

উত্স: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/ পরিবর্তন_সমনিকা


-2

আমার সমাধান:

; (function ($) {
$.each([ "toggle", "show", "hide" ], function( i, name ) {
    var cssFn = $.fn[ name ];
    $.fn[ name ] = function( speed, easing, callback ) {
        if(speed == null || typeof speed === "boolean"){
            var ret=cssFn.apply( this, arguments )
            $.fn.triggerVisibleEvent.apply(this,arguments)
            return ret
        }else{
            var that=this
            var new_callback=function(){
                callback.call(this)
                $.fn.triggerVisibleEvent.apply(that,arguments)
            }
            var ret=this.animate( genFx( name, true ), speed, easing, new_callback )
            return ret
        }
    };
});

$.fn.triggerVisibleEvent=function(){
    this.each(function(){
        if($(this).is(':visible')){
            $(this).trigger('visible')
            $(this).find('[data-trigger-visible-event]').triggerVisibleEvent()
        }
    })
}
})(jQuery);

উদাহরণ স্বরূপ:

if(!$info_center.is(':visible')){
    $info_center.attr('data-trigger-visible-event','true').one('visible',processMoreLessButton)
}else{
    processMoreLessButton()
}

function processMoreLessButton(){
//some logic
}

5
); আপনি সবাইকে বলতে উচিত যে আপনি আসল jQuery এর এর কোড ব্যবহার করেছি, এটা আরো আস্থা অনুপ্রাণিত করা হবে
aemonge

1
"আমার সমাধান"। এই লোকটির স্নায়ু
আন্দ্রে সিলভা

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