इवेंट श्रोता जब तत्व दिखाई देता है?


113

मैं एक टूलबार बना रहा हूं जो एक पेज में शामिल होने जा रहा है। डिव इसे इसमें शामिल करने जा रहा है जो डिफॉल्ट रूप से प्रदर्शित होगा: कोई नहीं । क्या ऐसा कोई तरीका है जिसे मैं सुनने के लिए अपने टूलबार पर एक ईवेंट श्रोता रख सकता हूं, जब यह दृश्यमान हो जाता है तो यह आरंभ कर सकता है? या क्या मुझे इसे युक्त पृष्ठ से एक चर पास करना होगा?

धन्यवाद


क्या यह उत्तर मदद करता है? stackoverflow.com/questions/1397251/…
kangax

@कांगैक्स, धन्यवाद। लेकिन इसके व्यापक रूप से लागू नहीं होने के बाद से मुझे लगता है कि मैं पूरे ईवेंट श्रोता के विचार को खरोंचने जा रहा हूं और एक अलग मार्ग जा रहा हूं।
जद इसाक्स

जावास्क्रिप्ट में "ऑनविजबल" घटना के कार्यान्वयन के लिए यह उत्तर देखें: stackoverflow.com/a/3807340/975097
एंडरसन ग्रीन


कृपया इसे देख सकते हैं। stackoverflow.com/questions/45429746/…
मार्टिन

जवाबों:


8

जावास्क्रिप्ट ईवेंट उपयोगकर्ता सहभागिता से निपटते हैं , यदि आपका कोड पर्याप्त रूप से व्यवस्थित है, तो आपको उसी स्थान पर आरंभीकरण फ़ंक्शन को कॉल करने में सक्षम होना चाहिए जहां दृश्यता में परिवर्तन होता है (यानी आपको myElement.style.displayकई स्थानों पर परिवर्तन नहीं करना चाहिए , इसके बजाय एक फ़ंक्शन / विधि कॉल करें जो करता है) यह और कुछ भी आप चाहते हो सकता है)।


8
लेकिन आप दृश्यता में परिवर्तन का पता लगाने में सक्षम कैसे होंगे (यानी, जैसे ही कोई तत्व दिखाई देता है, फ़ंक्शन को कॉल करें)?
एंडरसन ग्रीन

मुझे लगता है कि तुम ऐसा नहीं कर सकते। आप परिवर्तन का पता लगाने की कोशिश करने के बजाय क्या करेंगे, यह जानते हुए कि यह कहां उकसाया गया है, और अपना फोन वहां रखें। यदि दृश्यता में परिवर्तन कुछ ऐसा नहीं है जो आपके स्वयं के कोड के लिए सीधे ज़िम्मेदार है (जैसे कुछ परिवाद) और तर्क जिसके द्वारा होता है, बहुत विवादित है, तो मुझे लगता है कि आप भाग्य से बाहर हैं? :)
maltalef

6
मैंने इस प्रश्न को अस्वीकार कर दिया क्योंकि सभी अर्थों के बावजूद, यह वास्तविक मुद्दे के लिए अप्रासंगिक है। (यदि मैं किसी फ्रेम पर कोई भी प्रदर्शित नहीं करता हूं, तो सभी बच्चे तत्व अदृश्य हो जाते हैं)
सेबास

2
@ सबास, मैं वास्तव में यह नहीं समझता कि बच्चों की दृश्यता यहां क्यों मायने रखती है। वैसे भी, यदि उत्तर आपके लिए विशेष मामले (जो कुछ भी हो सकता है) के लिए उपयोगी नहीं था, लेकिन अधिकांश प्रोग्रामर के लिए एक समाधान (या स्पष्टीकरण क्यों एक समाधान नहीं है) की ओर इशारा करता है, यह अभी भी मेरी विनम्र राय में एक वैध जवाब है। यदि आप अन्य उत्तरों में से एक को बेहतर पसंद करते हैं (विशेष रूप से एक जिसे बाद के समय में बनाया गया था, जब तकनीक में सुधार हुआ और नए विकल्प उपलब्ध हुए), मेरा मानना ​​है कि सही उत्तर को बदलने का अनुरोध एक डाउनवोट से अधिक उपयुक्त होगा। किसी भी मामले में, सिर के लिए धन्यवाद :)
maltalef

2
@figha, बच्चों को नहीं, लेकिन अगर आप जो तत्व देख रहे हैं, वह एक ऐसे फ्रेम में है, जो प्रदर्शित नहीं है = कोई नहीं, तो आपके पास इसका कोई संकेत नहीं होगा।
सेबस

66

आगे बढ़ते हुए, नया HTML Intersection Observer API वह चीज़ है जिसकी आप तलाश कर रहे हैं। यह आपको एक कॉलबैक को कॉन्फ़िगर करने की अनुमति देता है जिसे कभी भी एक तत्व कहा जाता है, जिसे लक्ष्य कहा जाता है, या तो डिवाइस व्यूपोर्ट या एक निर्दिष्ट तत्व को इंटरसेक्ट करता है। यह क्रोम, फ़ायरफ़ॉक्स और एज के नवीनतम संस्करणों में उपलब्ध है। अधिक जानकारी के लिए https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_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
> इंटरसेक्शन ऑब्जर्वर एपीआई आपको एक कॉलबैक को कॉन्फ़िगर करने की अनुमति देता है जिसे जब भी एक तत्व कहा जाता है, लक्ष्य कहा जाता है, या तो डिवाइस व्यूपोर्ट या एक निर्दिष्ट तत्व को प्रतिच्छेद करता है;
स्टिल

1
ध्यान दें कि इंटरेक्शनऑब्जर्वर फिलहाल सफारी पर काम नहीं करता है। caniuse.com/#feat=intersectionobserver ऐसा लगता है कि प्रगति में एक पैच है। Bugs.webkit.org/show_bug.cgi?id=159475
Pic

8
जब IE इस तरह से कुछ के लिए समर्थन की कमी इस तरह से हमारे जीवन को बर्बाद करने से रोकने के लिए जा रहा है?
पीटर मूर

5
@PeterMoore जैसे ही आप इसका समर्थन करने की कोशिश करना बंद करते हैं। बस नहीं है।
जॉनी क्यों

4
जबरदस्त हंसी। कभी-कभी यह हमारा निर्णय नहीं है।
पीटर मूर

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

मुझे थोड़ी देर हो सकती है, लेकिन आप केवल इच्छित तत्व पर किसी भी परिवर्तन का निरीक्षण करने के लिए MutationObserver का उपयोग कर सकते हैं। यदि कोई परिवर्तन होता है, तो आपको यह देखना होगा कि तत्व प्रदर्शित किया गया है या नहीं।


4
यह तब काम नहीं करता है जब targetNode प्रदर्शित नहीं होता है क्योंकि पूर्वज प्रदर्शित नहीं होता है लेकिन फिर प्रदर्शित होता है।
मार्को एकस्टीन

Upvoted! : मैं एक और stackoverflow जवाब में यह प्रयोग किया जाता stackoverflow.com/questions/48792245/...
निक टिमर

दुर्भाग्य से, यह केवल तत्व पर इनलाइन शैलियों का उपयोग करते समय काम करता है, न कि जब परिवर्तन सीएसएस-क्लास के परिवर्तन का परिणाम होता है (जो कि अधिक संभावना परिदृश्य है, यह देखते हुए कि पूर्व स्थिति में आपके पास शायद पहले से ही पूर्ण प्रोग्रामेटिक नियंत्रण है)। फिडल जो इस मुद्दे को दिखाता है: jsfiddle.net/elmarj/uye62Lxc/4 । शैली-परिवर्तनों का अवलोकन करने के बारे में अधिक संपूर्ण चर्चा के लिए यहाँ देखें: dev.to/oleggromov/observes-style-changes---d4f
Elmar Jansen

वास्तव में यहाँ उपयोग करने के लिए सही ऑब्जर्वर एक IntersectionObserver- stackoverflow.com/a/52627221/2803743
kano

यह समाधान तब उपयोगी है जब आप किसी तत्व को चालू और बंद करना चाहते हैं, और उस तत्व का कोई प्रत्यक्ष नियंत्रण नहीं है, और प्रदर्शन मूल्य परिवर्तन पर प्रतिक्रिया करना चाहते हैं
एरन गोल्डिन

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);

DOM मानक भी उत्परिवर्तन घटनाओं को निर्दिष्ट करता है , लेकिन मुझे उनका उपयोग करने का कभी मौका नहीं मिला है, और मुझे यकीन नहीं है कि वे कितनी अच्छी तरह से समर्थित हैं। आप उन्हें इस तरह उपयोग करेंगे:

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

यह कोड मेरे सिर के ऊपर से है, इसलिए मुझे यकीन नहीं है कि यह काम करेगा।

सबसे अच्छा और आसान उपाय यह होगा कि आप अपने लक्ष्य को प्रदर्शित करने वाले फ़ंक्शन में कॉलबैक करें।


1
दिलचस्प है, धन्यवाद। कुछ वर्षों बाद, DOMAttrModified की स्थिति बदल गई है: "पदावनत। यह सुविधा वेब मानकों से हटा दी गई है। हालांकि कुछ ब्राउज़र अभी भी इसका समर्थन कर सकते हैं, यह गिराए जाने की प्रक्रिया में है।" (मोज़िला)
BurninLeo

MutationObserver नया नया है।
mindplay.dk

14

मुझे यही समस्या थी और इसे हमारी साइट के लिए हल करने के लिए एक jQuery प्लगइन बनाया।

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

यहाँ आप अपने उदाहरण के आधार पर इसका उपयोग कैसे करेंगे:

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

4
इस समाधान .is(':visible')के साथ उपयोग करता है setTimeout
Hp93

7

जैसा कि @figha का कहना है, यदि यह आपका अपना वेब पेज है , तो आपको तत्व को दिखाई देने के बाद आपको बस जो भी चलाने की आवश्यकता है, उसे चलाना चाहिए।

हालांकि, इस सवाल का जवाब देने के उद्देश्य से (और कोई भी क्रोम या फ़ायरफ़ॉक्स एक्सटेंशन बनाना , जहां यह एक सामान्य उपयोग का मामला है), म्यूटेशन सारांश और म्यूटेशन ऑब्जर्वर डोम परिवर्तन को ट्रिगर करने की अनुमति देगा।

उदाहरण के लिए, data-widgetDOM में जोड़े जाने वाले विशेषता वाले तत्वों के लिए किसी घटना को ट्रिगर करना । डेविड वाल्श के ब्लॉग से इस उत्कृष्ट उदाहरण को उधार लेना :

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आदि।


शायद इसलिए क्योंकि वह जानना चाहता है कि यह वास्तव में स्क्रीन पर कब है। मैं करता हूं, मैं केवल यह मान सकता हूं कि डाउनवॉटर का एक ही कारण है।
डेव हिलियर

प्रश्न का उत्तर नहीं देता है, और केवल लिंक पोस्ट करने की सलाह नहीं दी जाती है।
एलेक्स हॉल्सग्रोव

@AlexHolsgrove मैंने लिंक से एक उदाहरण जोड़ा है। चूंकि पोस्टर पृष्ठ पर टूलबार जोड़ने की बात करता है, इसलिए ऐसा लगता है कि वे किसी तीसरे पक्ष के पेज पर टूलबार जोड़ सकते हैं और DOM में किसी तत्व को जोड़े जाने की प्रतीक्षा कर रहे हैं, इस स्थिति में Mutations सबसे अच्छा API है।
मिकमेकाना

ध्यान दें कि यह अभी भी उस हिस्से को कवर नहीं करता है जो बताता है कि उत्परिवर्तन अवलोकन प्रक्रिया "दृश्यता" में कहां आता है।
माइक 'पोमैक्स' कमरमन्स


3

DOMAttrModified इवेंट श्रोता ब्राउज़र समर्थन पर टिप्पणी करने के लिए बस:

क्रॉस-ब्राउज़र समर्थन

इन घटनाओं को विभिन्न ब्राउज़रों में लगातार लागू नहीं किया जाता है, उदाहरण के लिए:

  • संस्करण 9 से पहले IE उत्परिवर्तन की घटनाओं का समर्थन नहीं करता था और संस्करण 9 में उनमें से कुछ को सही ढंग से लागू नहीं करता है (उदाहरण के लिए, DOMNodeInserted)

  • WebKit DOMAttrModified का समर्थन नहीं करता (वेबकिट बग 8191 और वर्कअराउंड देखें)

  • "म्यूटेशन नेम ईवेंट्स", यानी DOMElementNameChanged और DOMAttributeNameChanged फ़ायरफ़ॉक्स (संस्करण 11 के अनुसार) में समर्थित नहीं हैं, और शायद अन्य ब्राउज़रों में भी।

स्रोत: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Mutation_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
"मेरा समाधान"। इस आदमी पर तंत्रिका।
एंड्रे सिल्वा

@ AndréSilva शायद उन्होंने jQuery लिखा था। : ओ
एंड्रयू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.