मापदंडों के साथ जावास्क्रिप्ट इवेंट हैंडलर


89

मैं एक इवेंटहैंडलर बनाना चाहता हूं जो इवेंट और कुछ मापदंडों को पार करता है। समस्या यह है कि फ़ंक्शन को तत्व नहीं मिलता है। यहाँ एक उदाहरण है:

doClick = function(func){
    var elem = .. // the element where it is all about
    elem.onclick = function(e){
        func(e, elem);
    }
}
doClick(function(e, element){
    // do stuff with element and the event
});

अनाम फ़ंक्शन के बाहर 'एलेम' को परिभाषित किया जाना चाहिए। अनाम फ़ंक्शन के भीतर उपयोग करने के लिए मैं कैसे पारित तत्व प्राप्त कर सकता हूं? क्या इसे करने का कोई तरीका है?

और addEventListener के बारे में क्या? मुझे लगता है कि मैं इस कार्यक्रम को एक addEventListener के माध्यम से करने में सक्षम नहीं हो सकता हूँ?

अपडेट करें

मैं 'इस' के साथ समस्या को ठीक करने के लिए लग रहा था

doClick = function(func){
    var that = this;
    this.element.onclick = function(e){
        func(e, that);
    }
}

जहाँ इसमें यह सम्‍मिलित है कि फ़ंक्शन में मैं पहुंच सकता हूं।

AddEventListener

लेकिन मैं addEventListener के बारे में सोच रहा हूँ:

function doClick(elem, func){
    element.addEventListener('click', func(event, elem), false);
}

2
आपके पास आपके प्रश्न में शामिल तत्व, तत्व, तत्व हैं। क्या आप कम भ्रमित हो सकते हैं?
मिहाई

मुझे क्षमा करें, मैं अपनी स्थिति का एक उदाहरण बनाने की कोशिश कर रहा था लेकिन यह ठीक नहीं हुआ, मैंने कोड को अपडेट किया।
19-29 को sebas2day

आप के लिए देख रहे हो जाएगा e.target/ e.currentTarget?
रॉल्फ

1
कैसे एक पैरामीटर भेजने के लिए अगर im इस का उपयोग कर: OK.addEventListener ("क्लिक करें", यह.changeText.bind (यह));
अल्बर्टो एक्यूना

जवाबों:


103

मुझे समझ में नहीं आ रहा है कि आपका कोड क्या करने की कोशिश कर रहा है, लेकिन आप फ़ंक्शन क्लोजर के फायदों का उपयोग करके किसी भी घटना हैंडलर में चर उपलब्ध करा सकते हैं:

function addClickHandler(elem, arg1, arg2) {
    elem.addEventListener('click', function(e) {
        // in the event handler function here, you can directly refer
        // to arg1 and arg2 from the parent function arguments
    }, false);
}

आपकी सटीक कोडिंग की स्थिति के आधार पर, आप हमेशा बहुत कुछ बंद कर सकते हैं जो आपके लिए चर तक पहुंच को संरक्षित करता है।

अपनी टिप्पणियों से, यदि आप इसे पूरा करने की कोशिश कर रहे हैं, तो यह है:

element.addEventListener('click', func(event, this.elements[i]))

फिर, आप इसे स्वयं क्रियान्वित करने वाले फ़ंक्शन (IIFE) के साथ कर सकते हैं, जो आपके द्वारा बंद किए जाने वाले तर्कों को कैप्चर करता है क्योंकि यह निष्पादित होता है और वास्तविक ईवेंट हैंडलर फ़ंक्शन देता है:

element.addEventListener('click', (function(passedInElement) {
    return function(e) {func(e, passedInElement); };
}) (this.elements[i]), false);

IIFE कैसे काम करता है, इसके बारे में अधिक जानकारी के लिए, इन अन्य संदर्भों को देखें:

अनाम फ़ंक्शन के अंदर जावास्क्रिप्ट रैपिंग कोड

जावास्क्रिप्ट में तुरंत-आमंत्रित फ़ंक्शन अभिव्यक्ति (IIFE) - पासिंग jQuery

जावास्क्रिप्ट स्वयं उपयोग करने वाले अनाम कार्यों के लिए अच्छे उपयोग के मामले क्या हैं?

यह अंतिम संस्करण शायद यह देखना आसान है कि यह इस तरह क्या कर रहा है:

// return our event handler while capturing an argument in the closure
function handleEvent(passedInElement) {
    return function(e) {
        func(e, passedInElement); 
    };
}

element.addEventListener('click', handleEvent(this.elements[i]));

.bind()कॉलबैक में तर्कों को जोड़ने के लिए उपयोग करना भी संभव है । आपके द्वारा पास किए जाने वाले किसी भी तर्क .bind()को उन तर्कों के लिए प्रस्तुत किया जाएगा जो कॉलबैक के पास होंगे। तो, आप ऐसा कर सकते हैं:

elem.addEventListener('click', function(a1, a2, e) {
    // inside the event handler, you have access to both your arguments
    // and the event object that the event handler passes
}.bind(elem, arg1, arg2));

हाँ यह लगभग मैं क्या करने की कोशिश कर रहा हूँ, लेकिन क्या होगा अगर अनाम फ़ंक्शन addClickHandler द्वारा पैरामीटर के रूप में पारित हो जाता है और आप इस फ़ंक्शन को इवेंट के साथ कुछ पैरामीटर देना चाहते हैं जैसे: element.addEventListener ('क्लिक', func (इवेंट) this.elements [i]));
20 सितंबर को sebas2day

5
@ sebas2day - आप ऐसा नहीं कर सकते element.addEventListener('click', func(event, this.elements[i]))। जावास्क्रिप्ट सिर्फ इस तरह से काम नहीं करता है। क्लोजर का उपयोग करते हुए उसके आस-पास अन्य तरीके हैं, लेकिन आप इसे उस तरह से नहीं कर सकते जैसे आपने लिखा था। addEventListener यह बिल्कुल एक तर्क (घटना) के साथ कॉलबैक है और आप इसे किसी भी तरह से बदल नहीं सकते हैं।
jfriend00

मैंने अपने उत्तर के अंत में ऐसा करने का एक और उदाहरण जोड़ा।
जॉइटीआर 00

@ jfriend00 आप क्या कर सकते हैं बाँध विधि का उपयोग करें। function eventFunction (arg, evt) { console.log(arg[0],arg[1],arg[2]) console.log(evt) } var el = document.getElementById('elementID'); el.addEventListener('click', eventFunction.bind(el,[1,2,3])) ध्यान दें कि फ़ंक्शन के लिए तर्क में ईवेंट तर्क हमेशा अंतिम होता है, और इसे बाइंड विधि में स्पष्ट रूप से घोषित नहीं किया जाता है।
नाइट योशी

2
@ Bosh19 - आपके द्वारा पूछे गए निर्माण को समझाने के लिए मैंने अपने उत्तर के अंत में जो जोड़ा है, उसे देखें। यह एक तुरंत लागू फ़ंक्शन अभिव्यक्ति (IIFE) है जो अनिवार्य रूप से एक गुमनाम घोषित फ़ंक्शन है जिसे तुरंत निष्पादित किया जाता है। यह एक फ़ंक्शन को परिभाषित करने और फिर इसे कॉल करने के लिए एक शॉर्टकट है - जब आप शरीर को इनलाइन चाहते हैं तो यह उपयोगी होगा और इसे कहीं और नहीं बुलाया जाएगा, इसलिए इसे नाम की आवश्यकता नहीं है।
jfriend00

28

यह एक पुराना सवाल है, लेकिन एक आम है। तो मुझे यह एक यहाँ जोड़ने के लिए।

साथ में तीर समारोह वाक्य रचना आप इसे और अधिक संक्षिप्त तरीका है, क्योंकि यह lexically आबद्ध है और श्रृंखलित किया जा सकता है हासिल कर सकते हैं।

एक तीर समारोह अभिव्यक्ति एक नियमित रूप से कार्य अभिव्यक्ति के लिए एक वाक्यात्मक रूप से कॉम्पैक्ट विकल्प है, हालांकि इस, तर्क, सुपर, या new.target कीवर्ड के अपने बाइंडिंग के बिना।

const event_handler = (event, arg) => console.log(event, arg);
el.addEventListener('click', (event) => event_handler(event, 'An argument'));

यदि आपको इवेंट श्रोता को साफ करने की आवश्यकता है:

// Let's use use good old function sytax
function event_handler(event, arg) {
  console.log(event, arg);
}

// Assign the listener callback to a variable
var doClick = (event) => event_handler(event, 'An argument'); 

el.addEventListener('click', doClick);

// Do some work...

// Then later in the code, clean up
el.removeEventListener('click', doClick);

यहाँ पागल एक लाइनर है:

// You can replace console.log with some other callback function
el.addEventListener('click', (event) => ((arg) => console.log(event, arg))('An argument'));

अधिक विनम्र संस्करण : किसी भी समझदार काम के लिए अधिक उपयुक्त।

el.addEventListener('click', (event) => ((arg) => {
  console.log(event, arg);
})('An argument'));

2
यह एक उचित समाधान की तरह लगता है लेकिन जब आपको उसी ईवेंट श्रोता को निकालना हो तो क्या होगा?
दुष्यंत सभरवाल

@SnnSnn: +1। मैंने इवेंट हैंडलर को एक क्लास प्रॉपर्टी प्रदान करने के लिए इसका उपयोग किया। मैं अभी अंदर आया thisऔर हैंडलर को इसकी आवश्यकता थी।
रोबॉट्रॉन

यदि मेरी समझ सही है, तो आप वास्तव में अपने ईवेंट हैंडलर के रूप में एक अनाम फ़ंक्शन पास कर रहे होंगे: (e) => {....} और न कि yourEventHandlerFunction ()। यदि आप बाद में ईवेंट हैंडलर को निकालना चाहते हैं, तो यह समस्या पैदा करेगा, क्योंकि आप एक अनाम फ़ंक्शन से शुरू हुए हैं ???
पावटाकर

उत्तर स्पष्ट रूप से बताता है कि इवेंट श्रोता को कैसे हटाया जाए, इसलिए वहां कोई समस्या नहीं है।
snnsnn

9

कुछ आप कोशिश कर सकते हैं बाँध विधि का उपयोग कर रहा है, मुझे लगता है कि यह वही प्राप्त करता है जो आप के लिए पूछ रहे थे। अगर और कुछ नहीं, यह अभी भी बहुत उपयोगी है।

function doClick(elem, func) {
  var diffElem = document.getElementById('some_element'); //could be the same or different element than the element in the doClick argument
  diffElem.addEventListener('click', func.bind(diffElem, elem))
}

function clickEvent(elem, evt) {
  console.log(this);
  console.log(elem); 
  // 'this' and elem can be the same thing if the first parameter 
  // of the bind method is the element the event is being attached to from the argument passed to doClick
  console.log(evt);
}

var elem = document.getElementById('elem_to_do_stuff_with');
doClick(elem, clickEvent);

2

मूल प्रश्न के अद्यतन को देखते हुए, ऐसा लगता है कि घटना संचालकों को पारित करते समय संदर्भ ("यह") के साथ परेशानी है। मूल बातें यहां बताई गई हैं जैसे कि http://www.w3schools.com/js/js_function_invocation.asp

आपके उदाहरण का एक सरल कार्यशील संस्करण पढ़ सकता है

var doClick = function(event, additionalParameter){
    // do stuff with event and this being the triggering event and caller
}

element.addEventListener('click', function(event)
{
  var additionalParameter = ...;
  doClick.call(this, event, additionalParameter );
}, false);

यह भी देखें ) जावास्क्रिप्ट कॉल () और लागू () बाँध बनाम (?


2

संक्षिप्त जवाब:

x.addEventListener("click", function(e){myfunction(e, param1, param2)});

... 

function myfunction(e, param1, param1) {
    ... 
} 

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

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

नहीं, यह काम नहीं करता है। मैंने इसे ठीक वैसे ही परखा जैसे आपने किया और मेरी बात सर्वमान्य रही। अगर param1है noodleपहली बार addEventListener कहा जाता है, और दूसरी बार आप इसे कहते हैं, paramहै cheeseतो जब भी घटना श्रोता clickआग, param1पर सेट हो जाएगा cheeseऔर नहीं noodle। इसलिए, यह ईवेंट श्रोता के जोड़े जाने के समय मौजूद मूल्य को याद रखने के लिए "बंद" का उपयोग नहीं करता है। ऐसे परिदृश्य हैं जहां इवेंट श्रोता को कई बार जोड़ा जाना चाहिए जो कि मेरे बिंदु के मान्य होने के लिए सचित्र नहीं होना चाहिए।
तेतरादेव

मैं एक विशेषज्ञ नहीं हूं और मैंने पहले भी प्रोग्रामिंग में "बंद" के बारे में नहीं सुना है, इसलिए मुझे इससे कोई मतलब नहीं है।
user3093134

1
इसे जाँचने के लिए धन्यवाद, मैं आपके द्वारा पोस्ट किए गए लिंक पर अवश्य जाऊंगा। इसके अलावा, मेरा कहना है कि आप बहुत विनम्र और ईमानदार हैं, इसे बनाए रखें और एक अच्छा दिन लें :)
user3093134

0

thisके अंदर doThingsखिड़की वस्तु है। इसके बजाय यह प्रयास करें:

var doThings = function (element) {
    var eventHandler = function(ev, func){
        if (element[ev] == undefined) {
            return;
        }

        element[ev] = function(e){
            func(e, element);
        }
    };

    return {
        eventHandler: eventHandler
    };
};

-2
let obj = MyObject();

elem.someEvent( function(){ obj.func(param) } );

//calls the MyObject.func, passing the param.

परम एक कॉलबैक फ़ंक्शन (-say- वैश्विक संदर्भ में) भी हो सकता है और इसलिए अनुरोधित मापदंडों को आसानी से कहा जा सकता है।
υμυρης υζουζοΔηναρ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.