onclick () और onblur () आदेश जारी करना


104

मेरे पास एक इनपुट फ़ील्ड है जो एक कस्टम ड्रॉप-डाउन मेनू लाता है। मुझे निम्नलिखित कार्यक्षमता पसंद है:

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

यहाँ मेरा कार्यान्वयन है:

इनपुट फ़ील्ड में एक onblur()घटना होती है, जो innerHTMLउपयोगकर्ता द्वारा इनपुट फ़ील्ड के बाहर क्लिक करने पर मेनू को हटा देता है (अपने माता-पिता को एक रिक्त स्ट्रिंग पर सेट करके )। मेनू के अंदर के डिव में भी ऐसी onclick()घटनाएं होती हैं जो विशेष प्रसंस्करण को निष्पादित करती हैं।

समस्या यह है कि onclick()मेनू को क्लिक करने पर ईवेंट कभी फायर नहीं करते हैं, क्योंकि इनपुट फ़ील्ड की onblur()आग पहले और मेनू को हटा देती है, जिसमें onclick()एस भी शामिल है!

मैंने मेनू divs onclick()में onmousedown()और onmouseup()घटनाओं को विभाजित करके और माउस पर एक वैश्विक ध्वज सेट करके समस्या का हल किया जो कि माउस अप पर साफ़ किया जाता है, इस उत्तर में जैसा सुझाव दिया गया था । क्योंकि onmousedown()पहले आग लग जाती है onblur(), onblur()अगर ध्वज में से एक पर क्लिक किया गया था , तो ध्वज सेट किया जाएगा, लेकिन स्क्रीन पर कहीं और नहीं था। यदि मेनू पर क्लिक किया गया था, तो मैं तुरंत onblur()मेनू को हटाए बिना वापस आ गया , फिर onclick()आग के लिए प्रतीक्षा करें , जिस बिंदु पर मैं मेनू को सुरक्षित रूप से हटा सकता हूं।

क्या अधिक सुरुचिपूर्ण समाधान है?

कोड कुछ इस तरह दिखता है:

<div class="menu" onmousedown="setFlag()" onmouseup="doProcessing()">...</div>
<input id="input" onblur="removeMenu()" ... />

var mouseflag;

function setFlag() {
    mouseflag = true;
}

function removeMenu() {
    if (!mouseflag) {
        document.getElementById('menu').innerHTML = '';
    }
}

function doProcessing(id, name) {
    mouseflag = false;
    ...
}

जवाबों:


170

मैं आपके समान सटीक मुद्दा रख रहा था, मेरा UI ठीक उसी तरह से डिज़ाइन किया गया है जैसा आप वर्णन करते हैं। मैं बस के onClickसाथ मेनू आइटम के लिए जगह से समस्या का हल onMouseDown। मैंने और कुछ नहीं किया; नहीं onMouseUp, झंडे नहीं। इसने इन इवेंट हैंडलर की प्राथमिकता के आधार पर ब्राउज़र को स्वचालित रूप से पुन: आदेश देकर समस्या का समाधान किया, मेरे बिना किसी अतिरिक्त काम के।

क्या कोई कारण है कि यह आपके लिए भी काम नहीं करेगा?


3
यह वास्तव में काम करता है। मैंने एफएफ में इसका परीक्षण किया है और यह आकर्षण की तरह काम करता है।
सुप्रीम डॉल्फिन

3
यह काम करता हैं। ऐसा लगता है कि फ़ायरफ़ॉक्स, क्रोम और इंटरनेट एक्सप्लोरर में परीक्षण onmousedownसे पहले निष्पादित किया गया है onblur
टोनियोटी

11
यह ध्यान देने योग्य बात यह है कि व्यवहार को स्वाभाविक रूप से थोड़ा बदल दिया जाता है - क्लिक इंटरैक्शन को तब माउस अप के बजाय माउस डाउन पर नियंत्रित किया जाता है। अधिकांश लोगों के लिए जो ठीक हो सकते हैं (इस मामले में शामिल स्व) लेकिन कुछ कमियां हैं। सबसे विशेष रूप से मैं अक्सर क्लिक करता हूं फिर बटन को खींचता हूं यदि मैंने गर्भपात किया है, जो कि ऑनक्लिक को बुलाया जाने से रोकता है - यदि बटन एक गैर-शुद्ध फ़ंक्शन (डिलीट, पोस्ट आदि) करता है तो आप इसे संरक्षित करना और ध्वज दृष्टिकोण के साथ जा सकते हैं।
ब्रेज़ी

2
इस समय आपकी पहुँच के बारे में क्या आप माउस के साथ सेट पर क्लिक करें इसके बजाय आप सभी <बटन> तत्वों के लिए पहुँच
क्षमता

2
@ Ian-macfarlane द्वारा नीचे सूचीबद्ध उत्तर इस समस्या से निपटने का सही तरीका है। सारांश में ... अपनी इच्छित कार्रवाई के onMouseDownसाथ event.preventDefault() और onClickसाथ में।
कॉनल ट्रिनिट्रोटोल्यूने दा कोस्टा

48

onClickके साथ प्रतिस्थापित नहीं किया जाना चाहिए onMouseDown

हालांकि यह दृष्टिकोण कुछ हद तक काम करता है , दोनों मौलिक रूप से अलग-अलग घटनाएँ हैं जो उपयोगकर्ता की आँखों में अलग-अलग अपेक्षाएं हैं। इस मामले में उपयोग onMouseDownकरने के बजाय onClickइस मामले में आपके सॉफ़्टवेयर की भविष्यवाणी को बर्बाद कर देगा। इस प्रकार, दो घटनाएँ अविच्छिन्न हैं।

वर्णन करने के लिए: जब गलती से एक बटन पर क्लिक करते हैं, तो उपयोगकर्ता माउस क्लिक को दबाए रखने में सक्षम होने की उम्मीद करते हैं, तत्व के बाहर कर्सर को खींचें, और माउस बटन को छोड़ दें, अंततः कोई कार्रवाई नहीं हुई। onClickक्या ये। onMouseDownउपयोगकर्ता को माउस को दबाए रखने की अनुमति नहीं देता है, और इसके बजाय तुरंत उपयोगकर्ता के लिए किसी भी सहायता के बिना, एक कार्रवाई को ट्रिगर करेगा। onClickवह मानक है जिसके द्वारा हम कंप्यूटर पर क्रियाओं को ट्रिगर करने की अपेक्षा करते हैं।

इस स्थिति में, ईवेंट event.preventDefault()पर कॉल करें onMouseDownonMouseDownडिफ़ॉल्ट रूप से एक धमाकेदार घटना का कारण होगा, और ऐसा करने पर ऐसा नहीं किया जाएगा preventDefault। फिर, onClickबुलाया जाने का मौका होगा। एक धब्बा घटना तब भी होगी, उसके बाद ही onClick

सब के बाद, onClickघटना एक संयोजन है onMouseDownऔर onMouseUp, यदि और केवल अगर वे दोनों एक ही तत्व के भीतर होते हैं।


7
यह मेरे लिए सही समाधान था और टिप्पणी पूरी तरह से सही है - onMouseDown की जगह उपयोगकर्ता अनुभव के लिए भ्रमित है। मतदान किया है।
पॉल बार्टलेट

5
यह सही उत्तर होना चाहिए। इसे पोस्ट करने के लिए धन्यवाद
user1189352

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

1
यदि मैं घटना event.preventDefault()पर उपयोग करता onMouseDownहूं, तो मेरी onFocusघटना को नहीं बुलाया जाता है
बैटमैन

3

के onmousedownसाथ बदलें onfocus। जब टेक्स्टबॉक्स के अंदर फोकस होगा तो यह घटना शुरू हो जाएगी।

के onmouseupसाथ बदलें onblur। जिस समय आप अपने ध्यान को टेक्स्टबॉक्स से बाहर निकालेंगे, ऑनब्लूर निष्पादित होगा।

मुझे लगता है कि यह वही है जिसकी आपको आवश्यकता हो सकती है।

अद्यतन :

जब आप onfocus पर अपने कार्य को अंजाम देते हैं -> उन कक्षाओं को हटा दें जिन्हें आप onblur में लागू करेंगे और उन कक्षाओं को जोड़ेंगे जिन्हें आप onfocus को निष्पादित करना चाहते हैं।

तथा

जब आप onblur में अपने फ़ंक्शन को निष्पादित करते हैं -> उन कक्षाओं को हटा दें जिन्हें आप onfocus में लागू करेंगे और उन कक्षाओं को जोड़ेंगे जिन्हें आप onblur निष्पादित करना चाहते हैं।

मुझे ध्वज चर की कोई आवश्यकता नहीं दिखती।

अद्यतन 2:

आप ऑनमाउज़आउट और ऑनमॉउवर का उपयोग कर सकते हैं

onmouseover -Detects जब कर्सर इसके ऊपर होता है।

onmouseout -Detects जब कर्सर निकलता है।


मैंने अपने प्रश्न को स्पष्टता के लिए संपादित किया है। यह समाधान ध्वज स्थापित करने की आवश्यकता से कैसे बचता है? इसके अलावा, मैं उपयोग करता हूं onmousedown()और onmouseup()मेनू पर, टेक्स्टबॉक्स / इनपुट फ़ील्ड नहीं।
1 ''

मैं इस जवाब को अभी तक स्वीकार नहीं कर सकता क्योंकि मुझे नहीं पता कि यह सही है। क्या आप अपनी टिप्पणी में ऊपर दी गई चिंताओं का जवाब दे सकते हैं?
1 ''

ज़रूर, मैं देख सकता हूँ कि आप क्या कर सकते हैं onmouseover और onmouseout का उपयोग उसी तरह कर सकते हैं जैसा मैं वर्तमान में कर रहा हूँ, जब माउस मेनू पर हो तो एक ध्वज सेट करें। हालाँकि, मुझे अभी भी लगता है कि आपको ऑनमाउज़र में एक ध्वज स्थापित करने की आवश्यकता होगी, जिसे ऑनमाउटआउट में मंजूरी दे दी गई है, ताकि आपको पता चले कि क्या आप क्लिक करने पर मेनू पर थे। क्या आप ऐसे तरीके के बारे में सोच सकते हैं जिसमें झंडा लगाने की जरूरत न हो?
1 ''

क्या मैं आपको कोड देख सकता हूं ... इसे एक फ़ेडल में डाल सकता हूं ... यदि मैं परिणाम नहीं देखता हूं तो संबंधित भाग और पूरी तरह से ठीक रख दूंगा। कोड को देखें ..
HIRA THAKUR


2

एक और अधिक सुरुचिपूर्ण (लेकिन कम संभावना वाला) समाधान:

मेनू को हटाने के लिए इनपुट के ऑनब्लूर का उपयोग करने के बजाय, उपयोग करें document.onclick, जो बाद में आग लगाता है onblur

हालाँकि, इसका अर्थ यह भी है कि इनपुट हटाए जाने पर मेनू हटा दिया जाता है, जो कि अवांछित व्यवहार है। एक सेट input.onclickके साथ event.stopPropagation()दस्तावेज़ क्लिक करें घटना के लिए क्लिक के प्रचार से बचने के लिए।


5
खैर, इस जवाब के साथ समस्या है, हालांकि, अगर यह एक क्लिक की घटना नहीं थी जो धब्बा को ट्रिगर करती थी। क्या होगा यदि उपयोगकर्ता इनपुट से बाहर निकाल दिया गया है? यह धब्बा घटना को गति प्रदान करेगा लेकिन फ़्लायआउट मेनू अभी भी दिखाई देगा।
क्रिस्टोफ़

0

onfocus द्वारा परिवर्तन पर क्लिक करें

भले ही onblur और onclick बहुत अच्छी तरह से साथ नहीं मिलता है, लेकिन जाहिर है onfocus और हाँ onblur। मेनू बंद होने के बाद भी onfocus अभी भी अंदर क्लिक किए गए तत्व के लिए मान्य है।

मैंने किया और यह काम किया।


-7

आप setIntervalअपने onBlurहैंडलर के अंदर एक फंक्शन का उपयोग कर सकते हैं , जैसे:

<input id="input" onblur="removeMenu()" ... />

function removeMenu() {
    setInterval(function(){
        if (!mouseflag) {
            document.getElementById('menu').innerHTML = '';
        }
    }, 0);
}

setIntervalसमारोह अपने निकाल देंगे onBlur समारोह बाहर कॉल स्टैक 0 से निर्धारित समय है, क्योंकि आप जोड़ने के लिए, इस समारोह के तुरंत बाद अन्य ईवेंट हैंडलर समाप्त बुलाया जाएगा


5
setIntervalएक बुरा विचार है, आप इसे कभी रद्द नहीं कर रहे हैं, इसलिए यह लगातार आपके कार्य को चलाएगा और सबसे अधिक संभावना है कि आपकी साइट अधिकतम सीपीयू का उपयोग करें। का प्रयोग करें setTimeoutबजाय आप इस तकनीक (जो मैं अनुशंसा नहीं करते हैं) का उपयोग करने जा रहे हैं। आपके ऐप को कुछ घटनाओं के समय पर निर्भर करना जोखिम भरा व्यवसाय है।
केसी

6
डांसर रॉबिनसन होगा! खतरा! रेस की हालत आगे!
गोरेडेक्स

मैं मूल रूप से इस समाधान (अच्छी तरह से setTimeoutनहीं setInterval) के साथ आया था, लेकिन मुझे 250सही क्रम में समय से पहले एमएस तक इसे टक्कर देना पड़ा । यह बग शायद अभी भी धीमे उपकरणों पर मौजूद है और यह देरी को भी ध्यान देने योग्य बनाता है। मैंने कोशिश की onMouseDownऔर यह ठीक काम करता है। मुझे आश्चर्य है कि अगर इसे स्पर्श घटनाओं की भी आवश्यकता है।
ब्रेनन Cheung

यदि आप वास्तव में onClick का उपयोग करना चाहते हैं, तो अंतराल जैसा कुछ बुरा नहीं है। लेकिन आप एक अंतराल के बजाय एक शर्त के साथ एक पुनरावर्ती टाइमआउट चाहते हैं ताकि यह हमेशा के लिए न चले। यह वही पैटर्न है जिसका उपयोग सेलेनियम सशर्त प्रतीक्षा करता है।
कैन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.