প্যারামিটার সহ জাভাস্ক্রিপ্ট ইভেন্ট হ্যান্ডলার


91

আমি একটি ইভেন্টহ্যান্ডলার তৈরি করতে চাই যা ইভেন্ট এবং কিছু পরামিতিগুলি পাস করে। সমস্যাটি হ'ল ফাংশনটি উপাদানটি পায় না। এখানে একটি উদাহরণ:

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

'এলেম' অবশ্যই বেনামি ফাংশনের বাইরে সংজ্ঞায়িত করা উচিত। বেনামে ফাংশনটিতে কীভাবে উত্তীর্ণ উপাদানটি ব্যবহার করতে পারি? এই কাজ করতে একটি উপায় আছে কি?

এবং অ্যাডএভেন্টলিস্টনার সম্পর্কে কী? আমি কি কোনও অ্যাডভেন্টলিস্টনারের মাধ্যমে ইভেন্টটি পাস করতে সক্ষম হচ্ছি বলে মনে হয় না?

হালনাগাদ

আমি 'এটি' দিয়ে সমস্যার সমাধান করেছি বলে মনে হয়েছিল

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

যেখানে এটিতে এই উপাদানটি রয়েছে যা আমি ফাংশনে অ্যাক্সেস করতে পারি।

#EventListener

তবে আমি অ্যাডভেন্টলিস্টনার সম্পর্কে ভাবছি:

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

4
আপনার প্রশ্নের সাথে জড়িত এলিম, উপাদান, উপাদান রয়েছে। আপনি কি কম বিভ্রান্ত হতে পারেন?
মিহাই

আমি দুঃখিত, আমি আমার পরিস্থিতির উদাহরণ দেওয়ার চেষ্টা করছিলাম কিন্তু এটি ভাল হয়নি, আমি কোডটি আপডেট করেছি।
sebas2day

আপনি e.target/ খুঁজছেন হবে e.currentTarget?
রলফ

4
যদি আমি এটি ব্যবহার করে প্যারামিটার পাঠাতে হয়: Ok.addEventListener ("ক্লিক করুন", this.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]))

তারপরে, আপনি এটি একটি স্ব সম্পাদনকারী ফাংশন (আইআইএফই) দিয়ে করতে পারেন যা বন্ধের মধ্যে আপনি যে যুক্তিগুলি চান তা ক্যাপচার করে এটি বাস্তব ইভেন্ট হ্যান্ডলার ফাংশনটি সম্পাদন করে এবং ফেরত দেয়:

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

আইআইএফই কীভাবে কাজ করে সে সম্পর্কে আরও তথ্যের জন্য এই অন্যান্য উল্লেখগুলি দেখুন:

বেনামি ফাংশনের ভিতরে জাভাস্ক্রিপ্ট মোড়ানো কোড

জাভাস্ক্রিপ্টে তাত্ক্ষণিকভাবে অনুরোধ করা ফাংশন এক্সপ্রেশন (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));

হ্যাঁ এটি আমি প্রায় যা করতে চাইছি তবে বেনামে ফাংশনটি যদি অ্যাডক্লিকহ্যান্ডলার দ্বারা প্যারামিটার হিসাবে পাস হয়ে যায় এবং আপনি এই ফাংশনটিকে ইভেন্টের সাথে কিছু পরামিতি দিতে চান যেমন: এলিমেন্ট.এডএভেন্টলিস্টনার ('ক্লিক', ফানক (ইভেন্ট, this.elements [i]));
sebas2day

4
@ sebas2day - আপনি করতে পারবেন না element.addEventListener('click', func(event, this.elements[i]))। জাভাস্ক্রিপ্ট ঠিক সেভাবে কাজ করে না। ক্লোজার ব্যবহার করে এর চারপাশে অন্যান্য উপায় রয়েছে তবে আপনি যেভাবে লিখেছেন তা করতে পারবেন না। অ্যাডএভেন্টলিস্টনার একে কলব্যাককে ঠিক একটি যুক্তি (ইভেন্ট) দিয়ে কল করে এবং আপনি কোনওভাবেই এটি পরিবর্তন করতে পারবেন না।
jਫਰ00

আমি আমার উত্তরের শেষে এটি করার আরও একটি উদাহরণ যুক্ত করেছি।
jفر00

@ jender00 আপনি যা করতে পারেন তা হ'ল বাঁধাই পদ্ধতিটি। 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])) নোট করুন যে ইভেন্টের যুক্তিটি ফাংশনের পক্ষে যুক্তিতে সর্বদা শেষ থাকে এবং বাইন্ড পদ্ধতিতে সুস্পষ্টভাবে ঘোষিত হয় না।
নাইট ইয়োশি

4
@ বোশ 19 - আপনি যে নির্মাণ সম্পর্কে জিজ্ঞাসা করেছেন তা ব্যাখ্যা করতে আমার উত্তরটির শেষে আমি কী যুক্ত করেছি তা দেখুন। এটি একটি তাত্ক্ষণিকভাবে অনুরোধ করা ফাংশন এক্সপ্রেশন (IIFE) যা অবিলম্বে সম্পাদন করা হয় এমন একটি বেনামে ঘোষিত ফাংশন। এটি কোনও ফাংশনটি সংজ্ঞায়িত করার জন্য এবং এরপরে এটি কল করার শর্টকাট - যখন আপনি শরীরের ইনলাইন চান তখন দরকারী এবং এটি অন্য কোথাও ডাকা হবে না যাতে এটির নামের প্রয়োজন নেই।
jਫਰ00

29

এটি একটি পুরানো প্রশ্ন তবে একটি সাধারণ প্রশ্ন। সুতরাং এখানে এটি একটি যোগ করা যাক।

সঙ্গে তীর ফাংশন সিনট্যাক্স আপনি এটি আরো সংক্ষিপ্ত পথ যেহেতু এটি আভিধানিক যুক্ত করে করা হয় এবং শৃঙ্খলিত করা যাবে অর্জন করতে পারেন।

একটি তীর ফাংশন এক্সপ্রেশন হ'ল নিয়মিত ফাংশন এক্সপ্রেশনটির সিনট্যাক্টিক্যালি কমপ্যাক্ট বিকল্প, যদিও এটির নিজস্ব যুক্তি ব্যতীত, আর্গুমেন্ট, সুপার, বা নিউ স্টার্ট কীওয়ার্ডগুলি নেই।

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

4
এটি একটি যুক্তিসঙ্গত সমাধানের মতো মনে হচ্ছে তবে যখন আপনাকে একই ইভেন্ট শ্রোতাদের সরিয়ে ফেলতে হবে তখন কী হবে?
দুশিয়ন্ত সবরওয়াল

@ এসএনএনএসএনএন: +১। আমি ইভেন্ট হ্যান্ডলারকে কোনও শ্রেণির সম্পত্তি সরবরাহ করতে এটি ব্যবহার করেছি। আমি সবে পাস করেছি thisএবং হ্যান্ডলারটি যা প্রয়োজন তা অ্যাক্সেস করতে পারে।
রোবট্রন

4
যদি আমার বোঝাপড়াটি সঠিক হয়, আপনি আসলে আপনার ইভেন্ট হ্যান্ডলার হিসাবে একটি বেনামী ফাংশনটি কেটে যাবেন: (ই) => {....} এবং আপনার এভেন্টহ্যান্ডলারফানশন () নয়। আপনি ইভেন্ট হ্যান্ডলারটি পরে মুছে ফেলতে ইচ্ছুক হলে এটি সমস্যার সৃষ্টি করবে, যেহেতু আপনি কোনও বেনামি কার্যক্রমে পাস করে শুরু করেছেন ???
পাওয়ারআক্তার

উত্তর কীভাবে ইভেন্ট শ্রোতাদের অপসারণ করবেন তা স্পষ্টভাবে ব্যাখ্যা করে, সুতরাং সেখানে কোনও সমস্যা নেই।
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);

এছাড়াও জাভাস্ক্রিপ্ট কল দেখুন () এবং () বনাম বাঁধাই () প্রয়োগ করুন?


1

সংক্ষিপ্ত উত্তর:

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

... 

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

4
এটি সঠিকভাবে কাজ করে না। ইভেন্ট হ্যান্ডলারটি সেট হয়ে যাওয়ার পরে যদি আপনার প্যারামগুলির মান পরিবর্তন হয় তবে এটি অপ্রত্যাশিত ফলাফল আনবে কারণ এটি param1বা এর মানের সাথে বন্ধ হয় না param2। যদি এই মানগুলি পরিবর্তন হয় তবে ইভেন্ট হ্যান্ডলারটি তৈরি হওয়ার সময় সেগুলি মান হিসাবে সেট করা হবে না। এগুলি কেবল বর্তমান মান হিসাবে সেট করা হবে। তদ্ব্যতীত, ইভেন্ট শ্রোতার ফাংশনের ক্ষেত্রের বাইরে কোনও ভেরিয়েবল সেট করা এবং ইভেন্ট হ্যান্ডলারের সেই পরিবর্তনশীলটিকে উল্লেখ করা থেকে এটি আলাদা নয়, সুতরাং এটি পরামিতিগুলিতে মোটেও পাস করে না।
তেত্রদেব

আমি সত্যিই আপনার পয়েন্টটি পাইনি যাতে আমার প্রতিক্রিয়া বন্ধ হয়ে যায়। যাইহোক, ইভেন্ট হ্যান্ডলারটি একবার সেট হয়ে যায় (সবসময় আমি অনুমান করি না তবে সাধারণত কেউ এটি চায়)। দ্বিতীয়ত, এটি বেশিরভাগই বলে যে হ্যান্ডলারের ফাংশনটি আমার কাজ এবং এটিতে 2 পরামিতি প্লাস "ইভেন্ট" ভেরিয়েবল। তৃতীয়ত, হ্যাঁ এটি কাজ করে এবং ফলাফলগুলি প্রত্যাশার মতো হয়।
ব্যবহারকারীর 3093134

4
না, এটি কাজ করে না। আপনি যেমনটি করেছেন ঠিক তেমনই আমি এটি পরীক্ষা করেছি এবং আমার বক্তব্যটি বৈধ থাকবে। যদি param1হয় noodleপ্রথমবার addEventListener বলা হয়, এবং দ্বিতীয় সময় আপনি এটা কল, paramহল cheeseতারপর যখনই ঘটনা শ্রোতা clickআগুন, param1সেট করা হবে cheeseএবং noodle। সুতরাং, ইভেন্ট শ্রোতার সাথে যুক্ত হওয়ার সময় বিদ্যমান মানটি মনে করার জন্য এটি "ক্লোজার" ব্যবহার করে না। এমন পরিস্থিতিতে রয়েছে যেখানে ইভেন্ট শ্রোতাকে একাধিকবার যুক্ত করতে হবে যা আমার পয়েন্টটি বৈধ হওয়ার জন্য চিত্রিত করার দরকার নেই।
তেত্রদেব

আমি কোনও বিশেষজ্ঞ নই এবং আমি আগে প্রোগ্রামিংয়ের "ক্লোজার" শুনিনি, সুতরাং আপনি এর দ্বারা কী বোঝাতে চেয়েছেন তা আমি পাই না।
ব্যবহারকারী 3093134

4
এটি যাচাই করার জন্য আপনাকে ধন্যবাদ, আমি অবশ্যই আপনার পোস্ট করা লিঙ্কগুলি পরিদর্শন করব। এছাড়াও, আমি আপনাকে বলতে চাই যে আপনি খুব বিনয়ী এবং সৎ স্যার, এটি চালিয়ে যান এবং একটি ভাল দিন দিন :)
ব্যবহারকারী 3093134

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.

প্যারাম একটি কলব্যাক ফাংশনও হতে পারে (-সে-গ্লোবাল প্রসঙ্গে) এবং তাই সহজেই অনুরোধ করা প্যারামিটারগুলির সাথে কল-ব্যাক বলা যেতে পারে।
Βουζουναράς
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.