jQuery फ़ंक्शन .append के बाद


90

कैसे एक समारोह कॉल करने के लिए के बाद jQuery .appendपूरी तरह से किया जाता है?

यहाँ एक उदाहरण है:

$("#root").append(child, function(){
   // Action after append is completly done
});

समस्या: जब एक जटिल DOM संरचना को जोड़ा जाता है, तो एपेंड फंक्शन कॉलबैक के भीतर मूल तत्व के नए आकार की गणना गलत है। मान्यताएँ हैं कि DOM अभी भी पूरी तरह से लोड नहीं हुआ है, केवल जोड़ा गया जटिल DOM का पहला बच्चा है।


आपको ठीक-ठाक घटनाओं का सामना करना चाहिए; append()बहुत कम समय लगता है।
बोजैंगल्स

देखें stackoverflow.com/q/8840580/176140 (वेबकिट ब्राउज़र पर डोम
low रिफलो

: यह उपयोगी हो सकता है stackoverflow.com/a/1489987/1375015
Konstantin Schubert

जवाबों:


70

आपको यहां कई मान्य उत्तर मिले हैं, लेकिन उनमें से कोई भी वास्तव में आपको यह नहीं बताता है कि यह क्यों काम करता है।

जावास्क्रिप्ट आदेशों में एक समय में एक को निष्पादित किया जाता है, जब तक कि वे आने वाले क्रम में सिंक्रोनाइज़ नहीं करते हैं, जब तक कि आप स्पष्ट रूप से उन्हें टाइमआउट या अंतराल का उपयोग करके अतुल्यकालिक नहीं बताते हैं।

इसका मतलब है कि आपकी .appendविधि निष्पादित की जाएगी और कुछ और नहीं (किसी भी संभावित टाइमआउट या अंतराल जो मौजूद हो सकता है की अवहेलना) तब तक निष्पादित करेगा जब तक कि उस विधि ने अपना काम खत्म नहीं कर लिया।

संक्षेप में, कॉलबैक की कोई आवश्यकता नहीं है क्योंकि .appendसिंक्रनाइज़ किया जाएगा।


39
यह सब सच है, लेकिन यहां मेरा मुद्दा है: मैं जटिल डोम को जोड़ता हूं, और एपेंड के ठीक बाद, मैं रूट तत्व के नए आकार की गणना करता हूं, लेकिन यहां मुझे गलत संख्या मिली। और सोचो कि, समस्या यह है: DOM अभी भी पूरी तरह से भरा हुआ नहीं है, केवल पहला बच्चा (.append ("<div id =" child "> <div id =" subChild_with_SIZE "> </ div> </ div>"))
डेविड होरक

@ जीनडेव, इस आकार का आप क्या जिक्र कर रहे हैं? क्या यह बच्चों की राशि है, माता-पिता की ऊंचाई या यह क्या है कि आपको गणना करने की आवश्यकता है?
mekwall

1
@ marcus-ekwall jsfiddle.net/brszE/3 यह केवल लेखन पद्धति है, काम कोड नहीं,
डेविड होरैक

22
@ DavidHorák तो यह स्वीकृत उत्तर क्यों है? यह सच है कि भले ही परिवर्तन होता है, कोड तब तक ब्लॉक नहीं होगा जब तक कि पूर्ण रिफ्लो काफी आश्चर्यचकित न हो जाए क्योंकि इसमें 32 अप-वोट होते हैं! (या यह मेरा भी कारण नहीं है) उत्तर जैसा कुछ [यहां] ( stackoverflow.com/questions/) 8840580 /… ) अयस्क प्रासंगिक हो सकता है।
एंड्रियास

17
मैं एंड्रियास से सहमत हूं, यह उत्तर सही नहीं है। समस्या यह है कि भले ही एपेंड वापस आ गया हो, तत्व अभी भी डोम में उपलब्ध नहीं हो सकता है (ब्राउज़र निर्भर, कुछ ब्राउज़रों में काम करता है अन्य में टूट जाता है)। टाइमआउट का उपयोग करना अभी भी गारंटी नहीं देता है कि तत्व DOM में होगा।
सेवरुन

19

वैसे मुझे आकार पुनर्गणना के साथ बिल्कुल वही समस्या है और सिरदर्द के घंटों के बाद मुझे .append()कड़ाई से तुल्यकालिक व्यवहार करने से असहमत होना पड़ता है । कम से कम Google Chrome में। निम्नलिखित कोड देखें।

var input = $( '<input />' );
input.append( arbitraryElement );
input.css( 'padding-left' );

पैडिंग-लेफ्ट प्रॉपर्टी को फ़ायरफ़ॉक्स में सही तरीके से पुनर्प्राप्त किया गया है लेकिन यह क्रोम में खाली है। अन्य सभी सीएसएस गुणों की तरह मुझे लगता है। कुछ प्रयोगों के बाद मुझे सीएसएस 'गेट्टर' को setTimeout()10 एमएस देरी से लपेटने के लिए व्यवस्थित करना पड़ा जो मुझे पता है कि यूजीली नर्क के रूप में है, लेकिन क्रोम में काम करने वाला एकमात्र है। यदि आप में से किसी को भी इस मुद्दे को बेहतर तरीके से हल करने का एक विचार था, तो मैं बहुत आभारी रहूंगा।


15
इससे मुझे बहुत मदद मिली: stackoverflow.com/q/8840580/176140 - अर्थ, परिशिष्ट () IS तुल्यकालिक है, लेकिन DOM अपडेट नहीं है
schellmax

उस स्थिति में, सेटटाइमआउट बदसूरत नहीं है (केवल 10ms है)। हर बार जब आप "डोम" हेरफेर का अनुरोध करते हैं, तो क्रोम इसे निष्पादित करने से पहले आपके कोड के समाप्त होने का इंतजार करेगा। इसलिए, यदि आप आइटम कहते हैं। आइटम के बाद जाएं। इसके बाद, यह सिर्फ कुछ नहीं करेगा। जब आपका निष्पादन कार्य समाप्त हो जाता है, तब, यह आपके परिवर्तनों को DOM पर लागू करता है। यदि आपको जारी रखने से पहले "डोम" अपडेट की प्रतीक्षा करने की आवश्यकता है, तो बस अपने सीएसएस / डीओएम कार्रवाई करें, फिर सेटटाइमआउट (फ़ंक्शन () {आगे क्या करना है);) पर कॉल करें। V6 में सेटलआउट एक अच्छे पुराने "doevents" की तरह काम करता है! यह ब्राउज़र को उसके वेटिंग टास्क (अपडेट डोम) करने के लिए कहता है, और उसके बाद आपके कोड पर लौटता है।
foxontherock

उस उत्तर को देखें जो .ready()बहुत बेहतर और अधिक सुरुचिपूर्ण समाधान का उपयोग करता है।
मार्क कारपेंटर जूनियर

19

हालांकि मार्कस एकवाल एपेंड की समकालिकता के बारे में बिल्कुल सही है, मैंने यह भी पाया है कि विषम परिस्थितियों में कभी-कभी डोम ब्राउज़र द्वारा पूरी तरह से प्रदान नहीं किया जाता है जब कोड की अगली पंक्ति चलती है।

इस परिदृश्य में तो छायाकार समाधान सही पंक्तियों के साथ - पहले से ही उपयोग कर रहा है - हालाँकि यह आपके मूल परिशिष्ट में कॉल को श्रंखलाबद्ध करने के लिए बहुत सा है।

$('#root')
  .append(html)
  .ready(function () {
    // enter code here
  });

यह हर स्थिति में बिलकुल गलत और बेकार है। api.jquery.com/ready
केविन बी

हाय केविन, किस तरह से?
डैनियल - एसडीएस ग्रुप

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

मुझे नहीं लगता कि तैयार लोड किए गए दस्तावेज़ को लोड करने के लिए इंतजार करेंगे, बल्कि इसके बजाय पूरे डोम को लोड करने के लिए प्रतीक्षा करें। यह उत्तर लिखने में मुझे लगभग 3 साल लग गए लेकिन मुझे लगता है कि मैं ऊपर छाया छाया में टिप्पणी कर रहा था, लेकिन उस समय टिप्पणी करने की सुविधा नहीं थी।
डैनियल - एसडीएस ग्रुप

1
दरअसल, यह उम्मीद से बेहतर काम करता है। यहां किसी भी अन्य उत्तर से बेहतर है।
ब्लू

8

मैं यहाँ सभी उत्तरों पर आश्चर्यचकित हूँ ...

इसे इस्तेमाल करे:

window.setTimeout(function() { /* your stuff */ }, 0);

नोट 0 टाइमआउट। यह एक मनमाना संख्या नहीं है ... जैसा कि मैं समझता हूं (हालांकि मेरी समझ थोड़ी अस्थिर हो सकती है), दो जावास्क्रिप्ट ईवेंट कतारें हैं - एक मैक्रो इवेंट के लिए और एक माइक्रो ईवेंट के लिए। "बड़ी" स्कोप्ड कतार यूआई (और डीओएम) को अपडेट करने वाले कार्यों को रखती है, जबकि माइक्रो कतार त्वरित-कार्य प्रकार के संचालन करती है।

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

इसका मतलब यह है कि 0 का टाइमआउट सेट करना, इसे जावास्क्रिप्ट / ईवेंट के हिस्से में जावास्क्रिप्ट की ईवेंट कतार में डालता है, जिसे अगले संभावित मौके पर चलाया जा सकता है।

इसका मतलब यह है कि DOM सभी पिछली कतार की वस्तुओं (जैसे कि द्वारा डाला गया) के साथ अपडेट हो जाता है $.append(...);, और जब आपका कोड चलता है, तो DOM पूरी तरह से उपलब्ध हो जाता है।

(ps - मैंने इसे जावास्क्रिप्ट निनजा के जावास्क्रिप्ट से सीखा - एक उत्कृष्ट पुस्तक: https://www.manning.com/books/secrets-of-the-javascript-ninja )


मैं setTimeout()बिना जाने क्यों सालों से जोड़ रहा हूँ । स्पष्टीकरण के लिए धन्यवाद!
भाप जनित

5

मेरे पास एक और संस्करण है जो किसी के लिए उपयोगी हो सकता है:

$('<img src="http://example.com/someresource.jpg">').load(function() {
    $('#login').submit();
}).appendTo("body");

1
सोचने वाले लोगों के लिए यह हटा दिया गया है और हटा दिया गया है, यह सही है लेकिन आप अभी भी इसे ...on('load', function(){ ... यहाँ देख सकते हैं जैसे : stackoverflow.com/a/37751413/2008111
caramba

5

मैं एक ही समस्या में आया था और एक सरल समाधान पाया है। ऐप्पल फ़ंक्शन को तैयार करने के बाद एक दस्तावेज़ जोड़ें।

$("#root").append(child);
$(document).ready(function () {
    // Action after append is completly done
});


अच्छा लगा। यह मेरे लिए काम करता था (मैं हैंडलबार और JSON का उपयोग करके HTML को जोड़ रहा था और निश्चित रूप से एक नियमित दस्तावेज़। पहले से ही उस सभी के लिए बहुत जल्दी होता है)।
कैथरीन ओसबोर्न

1
@KatharineOsborne यह "नियमित दस्तावेज़ से पहले से अलग नहीं है।" दस्तावेज़। पहले से ही केवल एक विशिष्ट परिदृश्य में कहा जाता है, इसका उपयोग करने से यह अलग तरह से काम नहीं करता है।
केविन बी

अच्छी तरह से यह एक साल से अधिक हो गया है क्योंकि मैंने टिप्पणी छोड़ दी है, लेकिन IIRC, जहाँ आप इसे कहते हैं, का संदर्भ महत्वपूर्ण है (यानी एक फ़ंक्शन में)। बाद से कोड एक ग्राहक को सौंप दिया गया है, इसलिए मैं इसे वापस खोदने के लिए किसी भी अधिक तक पहुंच नहीं है।
कैथरीन ओसबोर्न

5

उपयोग करना MutationObserverjQuery appendविधि के लिए कॉलबैक की तरह कार्य कर सकता है :

मैंने इसे एक और प्रश्न में समझाया है , और इस बार मैं केवल आधुनिक ब्राउज़रों के लिए उदाहरण दूंगा:

// Somewhere in your app:
var observeDOM = (() => {
    var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;

    return function(obj, callback){
        if( MutationObserver ){
            // define a new observer
            var obs = new MutationObserver(function(mutations, observer){
                if( mutations[0].addedNodes.length || mutations[0].removedNodes.length )
                    callback(mutations);
            });
            // have the observer observe foo for changes in children
            obs.observe( obj, { childList:true, subtree:true });

            return obs;
        }
    }
})();

//////////////////
// Your code:

// setup the DOM observer (on the appended content's parent) before appending anything
observeDOM( document.body, ()=>{
    // something was added/removed
}).disconnect(); // don't listen to any more changes

// append something
$('body').append('<p>foo</p>');

+1। सभी उत्तरों में से आपका सबसे अच्छा फिट बैठता है। हालाँकि यह मेरे मामले में काम नहीं आया, एक मेज पर विभिन्न पंक्तियों को जोड़ते हुए, क्योंकि यह एक अनंत लूप में जाता है। प्लगइन जो तालिका को सॉर्ट करता है, वह DOM को बदल देगा ताकि वह प्रेक्षक को अनंत बार कॉल करे।
अजेवेदो

@ अज़ेवेदो - यह अनंत क्यों होगा? मुझे यकीन है कि यह परिमित है। वैसे भी, आप थोड़ा रचनात्मक होकर एक अतिरिक्त पंक्ति "घटना" से एक प्रकार की कार्यक्षमता को अलग कर सकते हैं । तरीके हैं।
vsync

जब सॉर्ट प्लगइन तालिका को छाँटता है तो यह ऑब्जर्वर (डोम बदला हुआ) को चालू करता है, जो फिर से सॉर्ट को ट्रिगर करेगा। अब मैं सोच रहा हूं ... मैं टेबल की पंक्तियों को गिन सकता हूं और पर्यवेक्षक को केवल सॉर्टर कॉल कर सकता हूं यदि पंक्तियों का काउंटर बदल दिया गया हो।
अजेवेदो

3

मुझे लगता है कि यह अच्छी तरह से उत्तर दिया गया है, लेकिन "सबचिल्ड_विथ_एसजेडई" को संभालने के लिए यह थोड़ा अधिक विशिष्ट है (यदि यह माता-पिता से आ रहा है, लेकिन आप इसे वहां से अनुकूलित कर सकते हैं जहां यह हो सकता है)

$("#root").append(
    $('<div />',{
        'id': 'child'
    })
)
.children()
.last()
.each(function() {
    $(this).append(
        $('<div />',{
            'id': $(this).parent().width()
        })
    );
});

2

$.when($('#root').append(child)).then(anotherMethod());


8
$.whenकेवल उन वस्तुओं के लिए काम करता है जिनकी प्रतिज्ञा वस्तु
लौटती है

यह काम कर रहा है, लेकिन कंसोल पर एक त्रुटि दे रहा है .. "तब एक फ़ंक्शन नहीं है"
करण दतवानी

1
यह केवल इसलिए काम करता है क्योंकि आप anotherMethod()एकदम से आह्वान कर रहे हैं .. इसे कॉलबैक के रूप में पारित नहीं किया जा रहा है।
15

इसका कोई अर्थ नहीं निकलता।
केविन बी

1

Jquery एपेंड फ़ंक्शन एक jQuery ऑब्जेक्ट देता है ताकि आप अंत में एक विधि को टैग कर सकें

$("#root").append(child).anotherJqueryMethod();

मुझे .append के बाद मुझे कस्टम जावास्क्रिप्ट फ़ंक्शन को कॉल करने की आवश्यकता है, मुझे रूट का पुनर्गणना आकार चाहिए
डेविड होरैक

आप संभवत: प्रत्येक विधि को jQuery का उपयोग कर सकते हैं, लेकिन परिशिष्ट एक तुल्यकालिक विधि है, इसलिए आपको अगली पंक्ति में जो कुछ भी करने की आवश्यकता है उसे करने के लिए बस ठीक होना चाहिए।
Dve

@JinDave, वास्तव में आपको क्या पुनर्गणना करने की आवश्यकता है? बच्चों की मात्रा, माता-पिता की ऊंचाई, या आकार का क्या मतलब है?
मेकवॉल

0

छवियों और अन्य स्रोतों के लिए आप इसका उपयोग कर सकते हैं:

$(el).one('load', function(){
    // completed
}).each(function() {
    if (this.complete)
        $(this).load();
});

0

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

    function processAppended(el){
        //process appended element
    }

    var remove = '<a href="#">remove</a>' ;
    $('li').each(function(){
        $(this).append(remove);   
        processAppended(this);    
    });​

-1

मोबाइल उपकरणों के लिए HTML5 को कोड करते समय मुझे इस समस्या का सामना करना पड़ा। कुछ ब्राउज़र / डिवाइस के संयोजन में त्रुटियां हुईं क्योंकि .append () विधि ने DOM में परिवर्तनों को तुरंत प्रतिबिंबित नहीं किया (जिससे JS विफल हो गया)।

इस स्थिति के लिए त्वरित और गंदे समाधान द्वारा किया गया था:

var appint = setInterval(function(){
    if ( $('#foobar').length > 0 ) {
        //now you can be sure append is ready
        //$('#foobar').remove(); if elem is just for checking
        //clearInterval(appint)
    }
}, 100);
$(body).append('<div>...</div><div id="foobar"></div>');

किसी कोड कंस्ट्रक्टर के खत्म होने के इंतजार में अंतराल का उपयोग कभी नहीं किया जाना चाहिए। यह पूरी तरह से अविश्वसनीय है।
गाबे हीमस्त्र

-1

हाँ, आप किसी भी DOM प्रविष्टि में कॉलबैक फ़ंक्शन जोड़ सकते हैं : JQuery के दस्तावेज़ों की जाँच करें: http://api.jquery.com/append/ और यहाँ एक व्यावहारिक, समान, उदाहरण: http://www.w3schools.com/jquery/ tryit.asp? फ़ाइल नाम = tryjquery_html_prepend_func
$myDiv.append( function(index_myDiv, HTML_myDiv){ //.... return child })



W3schools उदाहरण के साथ Fiddling, आप 2 पैरामीटर की जाँच कर सकते हैं, इस .prepend()पद्धति की जगह : $ ("p")। प्रीपेन्ड (फ़ंक्शन (n, pHTML) {रिटर्न "<b> यह p तत्व </ b> (\" <i) > "+ pHTML +" </ i> \ ") <b> का इंडेक्स" + n + "</ b> है।";
पेड्रो फरेरा

1
आप स्पष्ट रूप से है कि example..it यह एक कॉलबैक सामग्री कह जोड़ा जा चुका है नहीं करने के उद्देश्य समझ में नहीं आता, बल्कि एक कॉलबैक फ़ंक्शन रिटर्न जो क्या है संलग्न किया जाना है।
vsync

@vsync: पूरी तरह से। आपने स्पष्ट रूप से मेरे उत्तर को नहीं समझा। "बच्चा" है क्या जोड़ा जा चुका है और नहीं है जब यह संलग्न की गई।
पेड्रो फरेरा

-1

मैं हाल ही में एक ऐसी ही समस्या में भाग गया। मेरे लिए समाधान था कोलिटेशन को फिर से बनाना। मुझे प्रदर्शित करने का प्रयास करें:

var $element = $(selector);
$element.append(content);

// This Doesn't work, because $element still contains old structure:
$element.fooBar();    

// This should work: the collection is re-created with the new content:
$(selector).fooBar();

उम्मीद है की यह मदद करेगा!


इसने मेरी मदद नहीं की। :(
पाल

-1

Jquery में आप अपने परिशिष्ट के ठीक बाद उपयोग कर सकते हैं

$(function(){
//code that needs to be executed when DOM is ready, after manipulation
});

$ () एक फ़ंक्शन को कॉल करता है जो या तो DOM-ready कॉलबैक को पंजीकृत करता है (यदि कोई फ़ंक्शन इसे पास किया जाता है) या DOM से तत्व लौटाता है (यदि कोई चयनकर्ता स्ट्रिंग या तत्व इसे पास किया जाता है)

आप
jQuery http://api.jquery.com/ready/ में $ और $ () के बीच अधिक अंतर पा सकते हैं


-2

मुझे पता है कि यह सबसे अच्छा समाधान नहीं है, लेकिन सबसे अच्छा अभ्यास:

$("#root").append(child);

setTimeout(function(){
  // Action after append
},100);

8
मुझे नहीं लगता कि यह एक अच्छा अभ्यास है। 100 एक मनमानी संख्या है, और एक घटना में अधिक समय लग सकता है।
जस्सोन्चैर

1
जाने का गलत तरीका। यह हमेशा 100ms
axelvnk

यह क्यों काम करता है की एक व्याख्या के लिए मेरा जवाब यहां देखें (संख्या 0 हो सकती है, 100 नहीं): stackoverflow.com/questions/6068955/…
jleach

1
यह पहले से ही उपयोग किए गए उत्तरों की तुलना में कम से कम बेहतर अभ्यास है।
केविन बी

-4
$('#root').append(child);
// do your work here

परिशिष्ट में कॉलबैक नहीं है, और यह वह कोड है जो समकालिक रूप से निष्पादित होता है - इसका कोई जोखिम नहीं है


3
मुझे इस तरह की बहुत सी टिप्पणियाँ दिखाई देती हैं, और वे सहायक नहीं हैं। @ डेविड गिर गया, हाँ, जेएस आईएस समकालिक है, लेकिन डोम को अपडेट करने के लिए समय चाहिए। यदि आपको अपने DOM संलग्न तत्वों में हेरफेर करने की आवश्यकता है, लेकिन तत्वों को आपके DOM में अभी तक प्रदान नहीं किया गया है, भले ही ऐपेंड किया गया हो, आपका नया हेरफेर काम नहीं करेगा। । (उदाहरण के लिए: $ ( '# तत्व') पर ()।
NoobishPro

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.