jQuery लेबल पर क्लिक करते समय दो बार आग लगाओ


114

मैं कस्टम रेडियो बटन बनाने के लिए jQuery का उपयोग कर रहा हूं और मुझे एक समस्या है। जब रेडियो से जुड़े लेबल पर क्लिक करने से ईवेंट पर दो बार आग लग जाती है, अगर मैं केवल रेडियो पर ही क्लिक करता हूँ तो यह ठीक काम कर रहा है (वास्तव में यह रेडियो मैं क्लिक नहीं कर रहा हूँ, लेकिन div जो पूरे इनपुट और लेबल को लपेटता है)। यहाँ कोड है:

HTML:

 <div id="box">
     <asp:RadioButtonList ID="RadioButtonList1" runat="server">
         <asp:ListItem>RADIO1</asp:ListItem>
         <asp:ListItem>RADIO2</asp:ListItem>
         <asp:ListItem>RADIO3</asp:ListItem>
     </asp:RadioButtonList>
</div>

jQuery:

<script type="text/javascript">
       $(function () {
            $('#box').find('input:radio').each(function (i) {

            var input = $(this);
            // get the associated label using the input's id
            var label = $('label[for=' + input.attr('id') + ']');
            // wrap the input + label in a div
            $('<div class="custom-radio"></div>').insertBefore(input).append(label, input);

            var wrapperDiv = input.parent();

            // find all inputs in this set using the shared name attribute
            var allInputs = $('input[name=' + input.attr('name') + ']');

            // necessary for browsers that don't support the :hover pseudo class on labels
            label.hover(

            function () {
                $(this).addClass('hover');
            }, function () {
                $(this).removeClass('hover checkedHover');
            });

            //bind custom event, trigger it, bind click,focus,blur events
            wrapperDiv.bind('updateState', function () {
                if ($(this)[0].children[1].checked) {
                    allInputs.each(function () {
                        var curDiv = $('div > label[for=' + $(this).attr('id') + ']').parent();
                        curDiv.removeClass('custom-radio-checked');
                        curDiv.addClass('custom-radio');
                    });
                    $(this).toggleClass('custom-radio custom-radio-checked');
                }
                else {
                    $(this).removeClass('custom-radio-checked checkedHover checkedFocus');
                }

            })
            .trigger('updateState')
            .click(function () { console.log('click'); })
            .focus(function () {
                label.addClass('focus');
            }).blur(function () {
                label.removeClass('focus checkedFocus');
            });
        }); 
       });
   </script>

क्या इस व्यवहार का कोई हल है?

जवाबों:


130

जोड़ने का प्रयास करें:

evt.stopPropagation();
evt.preventDefault();

.bind () या .click (), जो भी आप देख रहे हैं। इसके अलावा, evtफंक्शन में पैरामीटर जोड़ें , जैसेfunction(evt) {...


9
ऐसा क्यों होता है?
चॉवी

8
क्योंकि नेस्टेड आइटम हैं। पदानुक्रम में प्रत्येक आइटम घटना को बुलबुला कर देगा।
जॉर्डन

7
यदि आप एक चेकबॉक्स के लिए इसका उपयोग कर रहे हैं, तो मेरे लिए यह भी आवश्यक था कि इनपुट को वास्तव में चेक किया जाए:jQuery('input').prop('checked', true);
डेविड सिनक्लेयर

6
return false;`evt.stopPropagation () के बराबर है; evt.preventDefault (); ( jQuery में )
तुलसी

193

मैंने ऊपर जोड़कर समाधान जोड़ने की कोशिश की:

evt.stopPropagation();
evt.preventDefault();

लेकिन काम नहीं किया। हालाँकि यह जोड़ना:

evt.stopImmediatePropagation();

समस्या का हल किया! :)


6
मुझे पता नहीं क्यों, लेकिन आपने जो कहा वह मेरे कोड के लिए काम की तरह लग रहा है। धन्यवाद!
22

8
उत्तम। यह ठीक काम किया! हालाँकि evt.stopPropagation(); evt.preventDefault();
दीदी

1
केवल इसने मेरे लिए काम किया, मैंने सफलता के बिना अन्य कार्यों की कोशिश की थी
मालीवालुर

1
इस जवाब ने मेरी जान बचाई!
साभार

1
यह मेरे लिए जवाब था!
डायल

73

क्लिक इवेंट को लेबल के बजाय इनपुट से बांधें। जब लेबल पर क्लिक किया जाता है - घटना तब भी घटित होगी क्योंकि, जैसा कि डस्टिन ने बताया है, लेबल पर एक क्लिक से इनपुट पर एक क्लिक ट्रिगर हो जाता है। यह लेबल को अपनी सामान्य कार्यक्षमता रखने की अनुमति देगा।

$('input').click();

के बजाय

$('label').click();

10
यह समाधान भी काम करता है यदि आपका मार्कअप लेबल-रैपिंग-इन-इनपुट तकनीक का उपयोग करता है, और सिर्फ मेरी पवित्रता को बचाया है: ओ)
Whelkaholism

4
आपको वास्तव changeमें रेडियो बटन पर भी बांधना चाहिए क्योंकि लेबल का पाठ क्लिक करने योग्य है - वे हमेशा रेडियो बटन को ही क्लिक नहीं करते हैं।
चॉवी

2
यदि बूटस्ट्रैपेसक label > inputसेटअप का उपयोग किया जाता है, तो यह उत्तर है, उत्तर नहीं। अपने कोड को जोड़ना evt.stopPropagation()या evt.preventDefault()प्रभावी रहते हुए, एक ऐसी हैक है जिसे उचित समाधान ज्यादा साफ और अधिक कुशल होने पर बचा जाना चाहिए।
इलास्टैस्टर

वाह वाह वाह, मैंने लगभग दो दिन बिताए, आखिरकार इससे मदद मिली और स्पष्टीकरण के लिए बहुत बहुत धन्यवाद
खुलता है-डेवलपर-

इसने मेरा दिन बचाया!
गाब ०६

11

यदि आप एक बाहरी कंटेनर को एक क्लिक तत्व के रूप में उपयोग करने की कोशिश कर रहे हैं, तो आप अपने क्लिक हैंडलर में घटनाओं को स्वाभाविक रूप से बुदबुदा सकते हैं और अपेक्षित तत्व के लिए परीक्षण कर सकते हैं। यदि आप एक फॉर्म के लिए एक अद्वितीय क्लिक ज़ोन की शैली बनाने की कोशिश कर रहे हैं तो यह परिदृश्य उपयोगी है।

<form>
<div id="outer">
    <label for="mycheckbox">My Checkbox</label>
    <input type="checkbox" name="mycheckbox" id="mycheckbox" value="on"/>
</div>
</form>
<script>
$('#outer').on('click', function(e){
    // this fires for #outer, label, and input
    if (e.target.tagName == 'INPUT'){
        // only interested in input
        console.log(this);
    }
});
</script>

1
यह मेरे लिए काम करता है क्योंकि मैं अभी भी चाहता था कि रेडियो बटन का चयन किया जाए। मैं नहीं चाहता था कि इवेंट हैंडलर दो बार सब कुछ करे।
चॉवी डेसी

1
इससे बच्चे चयनित नहीं हो पाएंगे। BTW, उसी कार्यक्षमता को प्राप्त करने के लिए एक बेहतर विकल्प होगाif (e.target == e.currentTarget) {}
चिकन सूप

9

इस आसान तरीके को ठीक करने के लिए, लेबल पर "के लिए" विशेषता को हटा दें। लेबल पर एक क्लिक भी संबंधित तत्व पर एक क्लिक को ट्रिगर करेगा। (जो आपके मामले में आपके क्लिक इवेंट को दो बार फायर कर रहा है।)

सौभाग्य


वास्तव में त्वरित समाधान। कोई यह तर्क दे सकता है कि यह मार्कअप के साथ खिलवाड़ है, लेकिन मुझे लगता है कि "फॉर" विशेषता का उद्देश्य ईवेंट प्रचार है। इसलिए यदि आप किसी अन्य तंत्र (jquery) का उपयोग कर रहे हैं तो हर तरह से "के लिए" से छुटकारा पाएं।
क्रिस हैरिंगटन

5

मैं आमतौर पर इस सिंटेक्स का उपयोग करता हूं

.off('click').on('click', function () { console.log('click'); })

के बजाय

.click(function () { console.log('click'); })

5

सबसे अच्छा जवाब टिप्पणियों के अंदर छिपा हुआ है:

आपको वास्तव changeमें रेडियो बटन पर भी बांधना चाहिए क्योंकि लेबल का पाठ क्लिक करने योग्य है - वे हमेशा रेडियो बटन को ही क्लिक नहीं करते हैं। - चॉवी 12 दिसंबर 13 '1:45 पर

इस बेला दिखाता है कि सभी अन्य समाधान - stopPropagation, stopImmediatePropagation, preventDefault, return false- या तो परिवर्तन कुछ भी नहीं या चेकबॉक्स / रेडियो कार्यक्षमता को नष्ट)। यह भी दर्शाता है कि यह एक वैनिला जावास्क्रिप्ट समस्या है, न कि jQuery की समस्या।

संपादित करें: एक और काम करने वाला समाधान जो मुझे सिर्फ एक और धागे में मिला onclickहै वह है लेबल के बजाय इनपुट को बांधना । अपडेटेड फ़िडेल


2

मैंने समाधान जोड़कर कोशिश की है।

evt.stopPropagation();
evt.preventDefault();

लेकिन काम नहीं किया।

जोड़ कर

evt.stopImmediatePropagation();

समस्या का हल किया! :)


1

E.preventDefault () के साथ समस्या; क्या यह रेडियो बटन की जाँच से लेबल क्लिक को रोकता है।

एक बेहतर समाधान यह होगा कि "चेक इन" की तरह त्वरित जाँच करें।

$("label").click(function(e){
  var rbtn = $(this).find("input");
  if(rbtn.is(':checked')){
  **All the code you want to have happen on click**
  }
)};

1
एक और भी रसीला समाधान सिर्फ उपयोग कर रहा होगा। पति की बजाय
.click

1
यह समाधान काम नहीं करता है यदि आपका कोड किसी उपयोगकर्ता को रेडियो बटन को रद्द करने की अनुमति देने वाला है। दोहरी आग इस मामले में गंभीर परेशानी का कारण बनती है।
जॉन्सल

1

मेरी समस्या थोड़ी अलग है, क्योंकि evt.stopPropagation();evt.preventDefault();मेरे लिए काम नहीं करता है, मैं बस return false;अंत में जोड़ता हूं , फिर यह काम करता है।

$("#addressDiv").on("click", ".goEditAddress", function(event) {
    alert("halo");
    return false;
});

1

मेरे मामले में समस्या यह थी कि मेरे पास एक समारोह में क्लिक इवेंट था और फ़ंक्शन को दो बार निष्पादित किया गया था .... फ़ंक्शन का प्रत्येक निष्पादन एक नया क्लिक इवेंट बनाता है। - फेसपालम -

फ़ंक्शन के बाहर क्लिक इवेंट को स्थानांतरित करने के बाद, सब कुछ उम्मीद के मुताबिक काम किया! :)


0

ट्रिगर तत्व के बाहर अपना इनपुट टैग लगाने का प्रयास करें, क्योंकि लेबल टैग क्लिक का अनुकरण करता है, इसलिए आपके पास हमेशा एक से अधिक कॉल होंगे।


0

मेरे पास एक ही मुद्दा था क्योंकि मैंने अपने रेडियो को लेबल के अंदर इस तरह से घोंसला बनाया था जैसे कि रेडियो_डिव से जुड़ा हैंडलर। नेस्टेड लेबल को हटाने से समस्या ठीक हो गई।

<div id="radio_div">
    <label>
       <input type="radio" class="community_radio" name="community_radio" value="existing">
           Add To Existing Community
    </label>
</div>

0

लेबल की जाँच की जाने वाली रेडियो / चेकबॉक्स को ट्रिगर करता है।

if ($(event.target).is('label')){
    event.preventDefault();
}

यह इस व्यवहार को ट्रिगर करने के लिए विशेष रूप से लेबल को रोकता है।


0

एक "= कुछ-आईडी" विशेषता के साथ लेबल पर क्लिक एक नया क्लिक ट्रिगर करता है, लेकिन केवल अगर लक्ष्य मौजूद है और एक इनपुट है। मैं इसे पूरी तरह से e.preventDefault () या इस तरह के सामान के साथ हल करने में सक्षम नहीं था इसलिए मैंने इसे इस तरह किया:

उदाहरण के लिए, यदि आपके पास यह संरचना है और क्लिक करने के लिए एक घटना चाहते हैं

<div class="some-class">
    <input type=checkbox" id="the-input-id" />
    <label for="the-input-id">Label</label>
</div>

क्या काम था:

$(document)
    .on('click', '.some-class', function(e) {
        if(
            $(e.target).is('label[for]')
            &&
            $('input#' + $(e.target).attr('for')).length
        ) {
            // This will trigger a new click so we are out of here
            return;
        }

        // else do your thing here, it will not get called twice
    })
;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.