জাভাস্ক্রিপ্টে গতিশীল উপাদানগুলিতে ইভেন্ট সংযুক্ত করুন


92

আমি গতিশীলভাবে তৈরি হওয়া একটি তালিকায় গতিশীলভাবে এইচটিএমএল ডেটা toোকানোর চেষ্টা করছি, কিন্তু যখন আমি গতিশীলভাবে তৈরি করা বোতামটির জন্য একটি অনক্লিক ইভেন্ট সংযুক্ত করার চেষ্টা করি তখন ঘটনাটি গুলি চালানো হয় না। সমাধান সত্যিই প্রশংসা করা হবে।

জাভাস্ক্রিপ্ট কোড:

document.addEventListener('DOMContentLoaded', function () {
document.getElementById('btnSubmit').addEventListener('click', function () {
    var name = document.getElementById('txtName').value;
    var mobile = document.getElementById('txtMobile').value;
    var html = '<ul>';
    for (i = 0; i < 5; i++) {
        html = html + '<li>' + name + i + '</li>';
    }
    html = html + '</ul>';

    html = html + '<input type="button" value="prepend" id="btnPrepend" />';
    document.getElementsByTagName('form')[0].insertAdjacentHTML('afterend', html);
});

document.getElementById('btnPrepend').addEventListener('click', function () {
    var html = '<li>Prepending data</li>';
    document.getElementsByTagName('ul')[0].insertAdjacentHTML('afterbegin', html);
});

});

এইচটিএমএল কোড:

<form>
    <div class="control">
        <label>Name</label>
        <input id="txtName" name="txtName" type="text" />
    </div>
    <div class="control">
        <label>Mobile</label>
        <input id="txtMobile" type="text" />
    </div>
    <div class="control">
        <input id="btnSubmit" type="button" value="submit" />
    </div>
</form>

আপনি কীভাবে এইচটিএমএল তৈরি করছেন?
jim0thy

4
আমি এটি বলব কারণ আপনি ইভেন্ট শ্রোতাদের সংযুক্ত করার চেষ্টা করার সময় উপাদানটির অস্তিত্ব নেই। - এই learn.jquery.com/events/event-delegation
ক্র্যাকারজ্যাক

4
আপনার অ্যাডভেন্টলিস্টনারটি বিটিএনসবিট-এর ইভেন্ট শ্রোতার কাছে নিয়ে যান
স্লবেটম্যান

উত্তর:


211

এটি আপনার উপাদানটি গতিশীলভাবে তৈরি হয়েছে এই কারণে। ইভেন্টটি পরিচালনা করতে আপনার ইভেন্ট প্রতিনিধি ব্যবহার করা উচিত ।

 document.addEventListener('click',function(e){
    if(e.target && e.target.id== 'brnPrepend'){
          //do something
     }
 });

jquery এটি সহজ করে তোলে:

 $(document).on('click','#btnPrepend',function(){//do something})

এখানে ইভেন্ট প্রতিনিধি ইভেন্ট প্রতিনিধি নিবন্ধ সম্পর্কে একটি নিবন্ধ


4
ধন্যবাদ! কখনও কখনও খাঁটি জেএস সমাধান আইফোনটিতে কাজ করে না, তবে যদি অন্য কোনও পিতামাতার ডিভিতে নথির পরিবর্তন হয়, উদাহরণস্বরূপ, এটি কাজ করে। প্রতিনিধি দলের সেরা সমাধান কী?
খোলিয়াভকো

4
@ খোলিয়াভকো আমি বলব যতক্ষণ না "অভিভাবক" উপাদানটি গতিশীলভাবে তৈরি হয় না ততক্ষণ এটি কাজ করা উচিত। আমি ইভেন্ট হ্যান্ডলারটিকে গতিশীল তৈরি ডি উপাদানটির প্রথম পিতামাতার সাথে আবদ্ধ করবো যাতে বিভিন্ন ইভেন্ট হ্যান্ডলারের মধ্যে কোনও বিরোধ না হয়
জিলিকেট

4
তবে কখনও কখনও এটি আইফোনে কাজ করে না, এমনকি "পিতামাতার" উপাদানটি গতিশীলভাবে তৈরি হয় না। এখানে এক্সপামল রয়েছে , এটি সমস্ত ব্রাউজারে কাজ করে তবে আইফোনটিতে নেই (সাফারি এবং এমনকি ক্রোম)। এবং আমি বুঝতে পারি না কেন।
খোলিয়াভকো

4
@ খোলিয়াভকো কেবল এই কারণে যে কোডেপেন সমস্ত কিছু মোড়ানোর জন্য একটি স্যান্ডবক্স ব্যবহার করে। আপনি যদি সত্যিই কোনও সাধারণ পৃষ্ঠায় এই কোডটি লিখেন তবে এটি কাজ করবে
জিলিকেট

4
অপ্রত্যাশিত ধরণের জবরদস্তি রোধ করতে অতিরিক্ত সমান চিহ্ন (===) যুক্ত করার কথা বিবেচনা করুন
স্ট্যাচাকো

19

ক্লিকগুলি ক্যাপচার করে document.bodyএবং তারপরে ইভেন্টের টার্গেটটি পরীক্ষা করে একটি কার্যকারিতা রয়েছে ।

document.body.addEventListener( 'click', function ( event ) {
  if( event.srcElement.id == 'btnSubmit' ) {
    someFunc();
  };
} );

4
বা নিকটস্থ পাত্রে
এমপ্লুংজন

নিখুঁত উত্তর!
রাহুল পুরোহিত

বাহ এটি আশ্চর্যজনক, এত সময় এবং কোড সাশ্রয় করে! :)
আনা মেডিউখ

4
দ্রষ্টব্য: ইভেন্ট.srcElement হ্রাস করা হয়েছে। পরিবর্তে ইভেন্ট.আরটিজেট ব্যবহার করার পরামর্শ দেওয়া হচ্ছে।
dsanchez

12

উপাদানগুলি sertোকানোর পরে আপনাকে অবশ্যই ইভেন্টটি সংযুক্ত করতে হবে, যেমন আপনি নিজের উপর একটি বৈশ্বিক ইভেন্ট সংযুক্ত করেন না documentতবে theোকানো উপাদানগুলিতে একটি নির্দিষ্ট ইভেন্ট।

যেমন

document.getElementById('form').addEventListener('submit', function(e) {
  e.preventDefault();
  var name = document.getElementById('txtName').value;
  var idElement = 'btnPrepend';
  var html = `
    <ul>
      <li>${name}</li>
    </ul>
    <input type="button" value="prepend" id="${idElement}" />
  `;
  /* Insert the html into your DOM */
  insertHTML('form', html);
  /* Add an event listener after insert html */
  addEvent(idElement);
});

const insertHTML = (tag = 'form', html, position = 'afterend', index = 0) => {
  document.getElementsByTagName(tag)[index].insertAdjacentHTML(position, html);
}
const addEvent = (id, event = 'click') => {
  document.getElementById(id).addEventListener(event, function() {
    insertHTML('ul', '<li>Prepending data</li>', 'afterbegin')
  });
}
<form id="form">
  <div>
    <label for="txtName">Name</label>
    <input id="txtName" name="txtName" type="text" />
  </div>
  <input type="submit" value="submit" />
</form>


4
এই পদ্ধতিটি কেবল সিএসআর (ক্লায়েন্ট সাইড রেন্ডারিং) এর জন্য কাজ করবে। এটি এসএসআর (সার্ভার-সাইড রেন্ডারিং) এর জন্য কাজ করবে না। এটি সিএসআর এবং এসএসআর উভয়ের পক্ষে কাজ করার জন্য, ইভেন্ট ডেলিগেশনই এর সমাধান:javascript document.addEventListener('click',function(e){ if(e.target && e.target.id== 'brnPrepend'){ //do something } });
ইয়েটেন্দ্র গোয়েল

পারফরম্যান্স কারণে, এই পদ্ধতির ভাল। সুতরাং এটি আপনার ব্যবহারের ক্ষেত্রে নির্ভর করে।
R3tep

8

পার্থক্যটি কীভাবে আপনি ডিওমে উপাদান তৈরি এবং সংযোজন করেন।

যদি আপনি এর মাধ্যমে একটি উপাদান তৈরি করেন document.createElement, ইভেন্ট শ্রোতা যুক্ত করুন এবং এটি ডিওমে যুক্ত করুন। আপনার ইভেন্টগুলিতে আগুন লাগবে।

আপনি যদি এই জাতীয় স্ট্রিং হিসাবে একটি উপাদান তৈরি করেন: এইচটিএমএল + = "<li> পরীক্ষা </ li>" `, এলেন্টটি প্রযুক্তিগতভাবে কেবল একটি স্ট্রিং। স্ট্রিংগুলিতে ইভেন্ট শ্রোতা থাকতে পারে না।

একটি সমাধান হ'ল প্রতিটি উপাদান তৈরি করে document.createElementতারপরে সেগুলি সরাসরি কোনও ডম উপাদানটিতে যুক্ত করা add

// Sample
let li = document.createElement('li')
document.querySelector('ul').appendChild(li)

3

আপনি এর অনুরূপ কিছু করতে পারেন:

// Get the parent to attatch the element into
var parent = document.getElementsByTagName("ul")[0];

// Create element with random id
var element = document.createElement("li");
element.id = "li-"+Math.floor(Math.random()*9999);

// Add event listener
element.addEventListener("click", EVENT_FN);

// Add to parent
parent.appendChild(element);

2
var __ = function(){
    this.context  = [];
    var self = this;
    this.selector = function( _elem, _sel ){
        return _elem.querySelectorAll( _sel );
    }
          this.on = function( _event, _element, _function ){
              this.context = self.selector( document, _element );
              document.addEventListener( _event, function(e){
                  var elem = e.target;
                  while ( elem != null ) {
                      if( "#"+elem.id == _element || self.isClass( elem, _element ) || self.elemEqal( elem ) ){
                          _function( e, elem );
                      }
                      elem = elem.parentElement;
                  }
              }, false );
     };

     this.isClass = function( _elem, _class ){
        var names = _elem.className.trim().split(" ");
        for( this.it = 0; this.it < names.length; this.it++ ){
            names[this.it] = "."+names[this.it];
        }
        return names.indexOf( _class ) != -1 ? true : false;
    };

    this.elemEqal = function( _elem ){
        var flg = false;
        for( this.it = 0; this.it < this.context.length;  this.it++ ){
            if( this.context[this.it] === _elem && !flg ){
                flg = true;
            }
        }
        return flg;
    };

}

    function _( _sel_string ){
        var new_selc = new __( _sel_string );
        return new_selc;
    }

এখন আপনি ইভেন্টটি রেজিস্ট্রেশন করতে পারেন,

_( document ).on( "click", "#brnPrepend", function( _event, _element ){
      console.log( _event );
      console.log( _element );
      // Todo

  });

ব্রাউজার সমর্থন

ক্রোম - 4.0, এজ - 9.0, ফায়ারফক্স - 3.5 সাফারি - 3.2, অপেরা - 10.0 এবং উপরে


2

আমি এটির সাহায্যে একটি ছোট গ্রন্থাগার তৈরি করেছি: গিটহাবের লাইব্রেরি উত্স

<script src="dynamicListener.min.js"></script>
<script>
// Any `li` or element with class `.myClass` will trigger the callback, 
// even elements created dynamically after the event listener was created.
addDynamicEventListener(document.body, 'click', '.myClass, li', function (e) {
    console.log('Clicked', e.target.innerText);
});
</script>

কার্যকারিতা jQuery.on () এর মতো।

প্রদত্ত নির্বাচকটির বিরুদ্ধে লক্ষ্য উপাদানটি পরীক্ষা করতে লাইব্রেরি এলিমেন্ট.ম্যাচগুলি () পদ্ধতি ব্যবহার করে । কোনও ইভেন্ট ট্রিগার করা হলে কলব্যাক কেবল তখনই ডাকা হয় যখন লক্ষ্য উপাদানটি নির্বাচিতের সাথে মেলে।


0

আমি জানি যে বিষয়টি খুব পুরানো তবে আমি নিজেকে খুব কার্যকর কোড তৈরি করতে কয়েক মিনিট সময় দিয়েছি যা খাঁটি ব্যবহার করে সূক্ষ্ম এবং খুব সহজভাবে কাজ করে JAVASCRIPT। এখানে একটি সাধারণ উদাহরণ সহ কোডটি দেওয়া হয়েছে:

String.prototype.addEventListener=function(eventHandler, functionToDo){
  let selector=this;
  document.body.addEventListener(eventHandler, function(e){
    e=(e||window.event);
    e.preventDefault();
    const path=e.path;
    path.forEach(function(elem){
      const selectorsArray=document.querySelectorAll(selector);
      selectorsArray.forEach(function(slt){
        if(slt==elem){
          if(typeof functionToDo=="function") functionToDo(el=slt, e=e);
        }
      });
    });
  });
}

// And here is how we can use it actually !

"input[type='number']".addEventListener("click", function(element, e){
	console.log( e ); // Console log the value of the current number input
});
<input type="number" value="25">
<br>
<input type="number" value="15">
<br><br>
<button onclick="addDynamicInput()">Add a Dynamic Input</button>
<script type="text/javascript">
  function addDynamicInput(){
    const inpt=document.createElement("input");
          inpt.type="number";
          inpt.value=Math.floor(Math.random()*30+1);
    document.body.prepend(inpt);
  }
</script>


0

আমি এই জন্য একটি সহজ ফাংশন করেছি।

_caseফাংশনটি আপনাকে কেবল লক্ষ্যটিই অর্জন করতে দেয় না, যেখানে ইভেন্টটি বাঁধেন সেখানে প্যারেন্টের উপাদানও পাবেন।

কলব্যাক ফাংশনটি ইভেন্টটি দেয় যা লক্ষ্য ( evt.target) এবং নির্বাচক ( this) এর সাথে মিলে যাওয়া মূল উপাদানটি ধারণ করে । উপাদানটি ক্লিক করার পরে আপনার প্রয়োজনীয় জিনিসগুলি এখানে করতে পারেন।

আমি এখনও ঠিক করি নি যে কোনটি ভাল, if-elseবাswitch

var _case = function(evt, selector, cb) {
  var _this = evt.target.closest(selector);
  if (_this && _this.nodeType) {
    cb.call(_this, evt);
    return true;
  } else { return false; }
}

document.getElementById('ifelse').addEventListener('click', function(evt) {
  if (_case(evt, '.parent1', function(evt) {
      console.log('1: ', this, evt.target);
    })) return false;

  if (_case(evt, '.parent2', function(evt) {
      console.log('2: ', this, evt.target);
    })) return false;

  console.log('ifelse: ', this);
})


document.getElementById('switch').addEventListener('click', function(evt) {
  switch (true) {
    case _case(evt, '.parent3', function(evt) {
      console.log('3: ', this, evt.target);
    }): break;
    case _case(evt, '.parent4', function(evt) {
      console.log('4: ', this, evt.target);
    }): break;
    default:
      console.log('switch: ', this);
      break;
  }
})
#ifelse {
  background: red;
  height: 100px;
}
#switch {
  background: yellow;
  height: 100px;
}
<div id="ifelse">
  <div class="parent1">
    <div class="child1">Click me 1!</div>
  </div>
  <div class="parent2">
    <div class="child2">Click me 2!</div>
  </div>
</div>

<div id="switch">
  <div class="parent3">
    <div class="child3">Click me 3!</div>
  </div>
  <div class="parent4">
    <div class="child4">Click me 4!</div>
  </div>
</div>

আশা করি এটা সাহায্য করবে!


0

আমি জিলিকাটে কাজ দ্বারা পোস্ট করা সমাধানটি খুঁজে পেয়েছি , তবে কেবলমাত্র লক্ষ্য উপাদানটি সর্বাধিক নেস্টেড। যদি এটি না হয় তবে পিতা-মাতার উপরে পুনরাবৃত্তি করার মাধ্যমে এটি সংশোধন করা যায়, অর্থাত্‍

function on_window_click(event)
{
    let e = event.target;

    while (e !== null)
    {
        // --- Handle clicks here, e.g. ---
        if (e.getAttribute(`data-say_hello`))
        {
            console.log("Hello, world!");
        }

        e = e.parentElement;
    }
}

window.addEventListener("click", on_window_click);

এছাড়াও নোট করুন আমরা কোনও বৈশিষ্ট্য দ্বারা ইভেন্টগুলি পরিচালনা করতে পারি, বা আমাদের শ্রোতাদের যে কোনও স্তরে সংযুক্ত করতে পারি। উপরের কোডটি একটি কাস্টম বৈশিষ্ট্য এবং ব্যবহার করে window। আমি সন্দেহ করি যে বিভিন্ন পদ্ধতির মধ্যে কোনও বাস্তববাদী পার্থক্য রয়েছে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.