javascript - ইভেন্ট গতিশীলভাবে তৈরি উপাদান উপর বাঁধাই?





jquery events unobtrusive-javascript (20)


এটি কোনও লাইব্রেরি বা প্লাগইন ছাড়াই একটি বিশুদ্ধ জাভাস্ক্রিপ্ট সমাধান:

document.addEventListener('click', function (e) {
    if (hasClass(e.target, 'bu')) {
        // .bu clicked
        // Do your thing
    } else if (hasClass(e.target, 'test')) {
        // .test clicked
        // Do your other thing
    }
}, false);

যেখানে আছে hasClass

function hasClass(elem, className) {
    return elem.className.split(' ').indexOf(className) > -1;
}

জীবন্ত উদাহরণ

ক্রেডিট ডেভ এবং সিম ভিদাস যায়

আরো আধুনিক JS ব্যবহার করে, hasClass প্রয়োগ করা যেতে পারে:

function hasClass(elem, className) {
    return elem.classList.contains(className);
}

আমার একটি কোড আছে যেখানে আমি একটি পৃষ্ঠায় সমস্ত নির্বাচিত বাক্সের মাধ্যমে লুপ করছি এবং mouse on/off তাদের প্রস্থের সাথে কিছুটা বিদীর্ণ করার জন্য একটি .hover ইভেন্টটি বাঁধাই mouse on/off

এই পৃষ্ঠা প্রস্তুত এবং ঠিক সূক্ষ্ম কাজ করে।

আমার সমস্যাটি হল যে প্রাথমিক লুপের পরে আমি যেকোনো নির্বাচন বাক্স অ্যাজ্যাক্স বা DOM এর মাধ্যমে যুক্ত করে ইভেন্টটি আবদ্ধ করব না।

আমি এই প্লাগিনটি ( jQuery লাইভ ক্যুইরি প্লাগইন ) খুঁজে পেয়েছি, কিন্তু প্লাগইন দিয়ে আমার পৃষ্ঠাগুলিতে আরও 5k যোগ করার আগে, আমি দেখতে চাই যে কেউ এটি করার উপায় জানেন কিনা, jQuery এর সাথে সরাসরি বা অন্য কোন বিকল্পের মাধ্যমে।




উপাদান এবং বদ্ধ ইভেন্ট তৈরি করার জন্য আরো নমনীয় সমাধান ( source )

// creating a dynamic element (container div)
var $div = $("<div>", {id: 'myid1', class: 'myclass'});

//creating a dynamic button
 var $btn = $("<button>", { type: 'button', text: 'Click me', class: 'btn' });

// binding the event
 $btn.click(function () { //for mouseover--> $btn.on('mouseover', function () {
    console.log('clicked');
 });

// append dynamic button to the dynamic container
$div.append($btn);

// add the dynamically created element(s) to a static element
$("#box").append($div);

দ্রষ্টব্য: এটি প্রতিটি উপাদানটির জন্য একটি ইভেন্ট হ্যান্ডলার উদাহরণ তৈরি করবে (লুপগুলিতে ব্যবহৃত হলে কর্মক্ষমতা প্রভাবিত করতে পারে)




<html>
    <head>
        <title>HTML Document</title>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
    </head>

    <body>
        <div id="hover-id">
            Hello World
        </div>

        <script>
            jQuery(document).ready(function($){
                $(document).on('mouseover', '#hover-id', function(){
                    $(this).css('color','yellowgreen');
                });

                $(document).on('mouseout', '#hover-id', function(){
                    $(this).css('color','black');
                });
            });
        </script>
    </body>
</html>



ইভেন্ট গতিশীলভাবে তৈরি উপাদান উপর বাঁধাই

একক উপাদান:

$(document.body).on('click','.element', function(e) {  });

শিশু উপাদান:

 $(document.body).on('click','.element *', function(e) {  });

যোগ * নোটিশ। একটি ঘটনা যে উপাদান সব শিশুদের জন্য ট্রিগার করা হবে।

আমি লক্ষ্য করেছি যে:

$(document.body).on('click','.#element_id > element', function(e) {  });

এটা আর কাজ করছে না, কিন্তু আগে কাজ করছিল। আমি গুগল CDN থেকে jQuery ব্যবহার করছি, কিন্তু আমি জানি না তারা এটি পরিবর্তন করেছে কিনা।




আপনি ব্যবহার করতে পারেন

$('.buttons').on('click', 'button', function(){
    // your magic goes here
});

অথবা

$('.buttons').delegate('button', 'click', function() {
    // your magic goes here
});

এই দুই পদ্ধতি সমতুল্য কিন্তু পরামিতি একটি ভিন্ন আদেশ আছে।

দেখুন: jQuery Delegate ইভেন্ট




আপনি লাইভ () পদ্ধতিটি ব্যবহার করতে পারেন (এমনকি নতুন তৈরি হওয়া) উপাদান এবং হ্যান্ডলারগুলিতে, অনকল ইভেন্টের মতো।

এখানে একটি নমুনা কোড লেখা আছে, যেখানে আপনি দেখতে পারেন কিভাবে লাইভ () পদ্ধতি নির্বাচিত উপাদানগুলি, এমনকি নতুন তৈরি হওয়াও ইভেন্টগুলির সাথে সম্পর্কযুক্ত করে:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Untitled Document</title>
    </head>

    <body>
        <script src="http://code.jquery.com/jquery-latest.js"></script>
        <script src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.16/jquery-ui.min.js"></script>

        <input type="button" id="theButton" value="Click" />
        <script type="text/javascript">
            $(document).ready(function()
                {
                    $('.FOO').live("click", function (){alert("It Works!")});
                    var $dialog = $('<div></div>').html('<div id="container"><input type ="button" id="CUSTOM" value="click"/>This dialog will show every time!</div>').dialog({
                                                                                                         autoOpen: false,
                                                                                                         tite: 'Basic Dialog'
                                                                                                     });
                    $('#theButton').click(function()
                    {
                        $dialog.dialog('open');
                        return('false');
                    });
                    $('#CUSTOM').click(function(){
                        //$('#container').append('<input type="button" value="clickmee" class="FOO" /></br>');
                        var button = document.createElement("input");
                        button.setAttribute('class','FOO');
                        button.setAttribute('type','button');
                        button.setAttribute('value','CLICKMEE');
                        $('#container').append(button);
                    });
                    /* $('#FOO').click(function(){
                                                     alert("It Works!");
                                                 }); */
            });
        </script>
    </body>
</html>



আমি একটি document স্তর ইভেন্ট শ্রোতা স্ক্রিপ্টিং এর পরিবর্তে একটি মডুলার ফাংশন ফ্যাশনে ইভেন্ট শ্রোতা স্থাপন করা পছন্দ। সুতরাং, আমি নীচের মত না। মনে রাখবেন, আপনি একই ইভেন্ট শ্রোতার সাথে একটি উপাদানকে সদস্যতা ত্যাগ করতে পারবেন না তাই একজন শ্রোতাকে একাধিক বার সংযুক্ত করার বিষয়ে চিন্তা করবেন না - শুধুমাত্র একটি লাঠি।

var iterations = 4;
var button;
var body = document.querySelector("body");

for (var i = 0; i < iterations; i++) {
    button = document.createElement("button");
    button.classList.add("my-button");
    button.appendChild(document.createTextNode(i));
    button.addEventListener("click", myButtonWasClicked);
    body.appendChild(button);
}

function myButtonWasClicked(e) {
    console.log(e.target); //access to this specific button
}




আপনি কেবল একটি ফাংশনে আপনার ইভেন্টের বাইন্ডিং কলটি আপলোড করতে পারেন এবং তারপরে এটি দুবার আহ্বান করতে পারেন: একবার ডকুমেন্টে প্রস্তুত এবং একবার আপনার ইভেন্টের পরে যা নতুন DOM উপাদান যোগ করে। যদি আপনি এটি করেন তবে আপনি বিদ্যমান উপাদানগুলিতে দুবার একই ইভেন্টটিকে বাঁধন এড়াতে চাইবেন তাই আপনাকে বিদ্যমান ইভেন্টগুলিকে অবাঞ্ছিত করতে হবে অথবা (ভাল) শুধুমাত্র নতুন তৈরি হওয়া DOM উপাদানগুলিতে আবদ্ধ হবে। কোডটি এমন কিছু দেখবে:

function addCallbacks(eles){
    eles.hover(function(){alert("gotcha!")});
}

$(document).ready(function(){
    addCallbacks($(".myEles"))
});

// ... add elements ...
addCallbacks($(".myNewElements"))



আমি $.bind পেতে একটি সমাধান খুঁজছেন ছিল এবং $.unbind । গতিশীলভাবে যোগ উপাদান মধ্যে সমস্যা ছাড়া কাজ $.unbind

হিসাবে on() ইভেন্টটি সংযুক্ত করার কৌশলটি চালায়, আমি যেগুলিতে এসেছি সেগুলিতে জাল বাঁধ নির্মাণ করার জন্য:

const sendAction = function(e){ ... }
// bind the click
$('body').on('click', 'button.send', sendAction );

// unbind the click
$('body').on('click', 'button.send', function(){} );



on() এর ডকুমেন্টেশন একটি ভাল ব্যাখ্যা আছে।

সংক্ষেপে:

ইভেন্ট হ্যান্ডলার শুধুমাত্র নির্বাচিত নির্বাচিত উপাদান শুধুমাত্র আবদ্ধ হয়; আপনার কোডটি .on() এ কল করার সময় পৃষ্ঠায় বিদ্যমান থাকা আবশ্যক।

সুতরাং নিম্নলিখিত উদাহরণে #dataTable tbody tr কোডটি তৈরি হওয়ার আগে বিদ্যমান থাকা আবশ্যক।

$("#dataTable tbody tr").on("click", function(event){
    console.log($(this).text());
});

যদি নতুন এইচটিএমএল পৃষ্ঠায় ইনজেকশন করা হয় তবে পরবর্তী ইভেন্ট হিসাবে ইভেন্ট ইভেন্ট হ্যান্ডলার সংযুক্ত করার জন্য নির্ধারিত ইভেন্টগুলি ব্যবহার করা আরও ভাল।

দায়িত্বপ্রাপ্ত ইভেন্টগুলির সুবিধা রয়েছে যে তারা পরবর্তী সময়ে নথিতে যোগ করা উত্তরসূরি উপাদানগুলি থেকে ইভেন্টগুলি প্রক্রিয়া করতে পারে। উদাহরণস্বরূপ, যদি টেবিলটি বিদ্যমান থাকে তবে ক্রমগুলি কোড ব্যবহার করে গতিশীলভাবে যুক্ত করা হয় তবে নিম্নলিখিতটি পরিচালনা করবে:

$("#dataTable tbody").on("click", "tr", function(event){
    console.log($(this).text());
});

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

একটি প্রতিনিধি-ইভেন্ট পদ্ধতির (দ্বিতীয় কোড উদাহরণ) একটি ইভেন্ট হ্যান্ডলারকে শুধুমাত্র একটি উপাদান, গোষ্ঠীর সাথে tbody এবং ইভেন্টটিকে শুধুমাত্র একটি স্তরের বুদ্বুদ করতে হবে (ক্লিক করা tbody থেকে tbody )।

দ্রষ্টব্য: ডিভিডেড ইভেন্টগুলি SVG জন্য কাজ SVG




আমি নির্বাচক ব্যবহার করে পছন্দ করি এবং আমি নথিতে এটি প্রয়োগ করি।

এটি নথিতে নিজেই আবদ্ধ এবং পৃষ্ঠা লোডের পরে উপস্থাপিত উপাদানগুলিতে প্রযোজ্য হবে।

উদাহরণ স্বরূপ:

$(document).on("click", $(selector), function() {
    // Your code here
});



ঘটনাটি ইতিমধ্যেই বিদ্যমান এমন পিতা-মাতার কাছে বদ্ধ করুন:

$(document).on("click", "selector", function() {
    // Your code here
});



ইভেন্টটি আবদ্ধ হওয়ার সময় উপস্থিত কোনও প্যারেন্ট নেই এবং যদি আপনার পৃষ্ঠাটি ক্রমান্বয়ে বর্গের নামের বোতাম সহ উপাদান তৈরি করে তবে আপনি ইভেন্টটিকে একটি পিতামাতার সাথে যুক্ত করবেন যা ইতিমধ্যে বিদ্যমান

$(document).ready(function(){
  //Particular Parent chield click
  $(".buttons").on("click","button",function(){
    alert("Clicked");
  });  
  
  //Dynamic event bind on button class  
  $(document).on("click",".button",function(){
    alert("Dymamic Clicked");
  });
  $("input").addClass("button");  
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="buttons">
  <input type="button" value="1">
  <button>2</button>
  <input type="text">
  <button>3</button>  
  <input type="button" value="5">  
  </div>
<button>6</button>




উপাদান স্থাপন করা হয় "MAIN" ক্লাস নোট নিন, উদাহরণস্বরূপ,

<div class="container">
     <ul class="select">
         <li> First</li>
         <li>Second</li>
    </ul>
</div>

উপরের দৃশ্যটিতে, jQuery মুখ্য বস্তুটি "কন্টেইনার" দেখতে হবে।

তারপরে আপনি মূলত উপ, li , এবং select হিসাবে ধারক অধীনে উপাদান নাম থাকবে:

$(document).ready(function(e) {
    $('.container').on( 'click',".select", function(e) {
        alert("CLICKED");
    });
 });



যখন আপনি jQuery(html, attributes) ব্যবহার করে গতিশীলভাবে তৈরি করেন তখন আপনি উপাদানটিতে ইভেন্ট সংযুক্ত করতে পারেন।

JQuery 1.8 অনুসারে , কোনও jQuery ইনস্ট্যান্স পদ্ধতি ( jQuery.fn একটি পদ্ধতি) দ্বিতীয় প্যারামিটারে প্রেরিত বস্তুর সম্পত্তি হিসাবে ব্যবহার করা যেতে পারে:

function handleDynamicElementEvent(event) {
  console.log(event.type, this.value)
}
// create and attach event to dynamic element
jQuery("<select>", {
    html: $.map(Array(3), function(_, index) {
      return new Option(index, index)
    }),
    on: {
      change: handleDynamicElementEvent
    }
  })
  .appendTo("body");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>




এই মত চেষ্টা করুন -

$(document).on( 'click', '.click-activity', function () { ... });



গতিশীলভাবে তৈরি উপাদানগুলি ক্লিকে প্রতিক্রিয়া জানায় না কেন এখানে:

var body = $("body");
var btns = $("button");
var btnB = $("<button>B</button>");
// `<button>B</button>` is not yet in the document.
// Thus, `$("button")` gives `[<button>A</button>]`.
// Only `<button>A</button>` gets a click listener.
btns.on("click", function () {
  console.log(this);
});
// Too late for `<button>B</button>`...
body.append(btnB);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>A</button>

একটি কার্যকারিতা হিসাবে, আপনি সব ক্লিক শুনতে এবং উৎস উপাদান চেক করতে হবে:

var body = $("body");
var btnB = $("<button>B</button>");
var btnC = $("<button>C</button>");
// Listen to all clicks and
// check if the source element
// is a `<button></button>`.
body.on("click", function (ev) {
  if ($(ev.target).is("button")) {
    console.log(ev.target);
  }
});
// Now you can add any number
// of `<button></button>`.
body.append(btnB);
body.append(btnC);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>A</button>

এই "ইভেন্ট প্রতিনিধি" বলা হয়। ভাল খবর, এটি jQuery একটি বিল্টিন বৈশিষ্ট্য :-)

var i = 11;
var body = $("body");
body.on("click", "button", function () {
  var letter = (i++).toString(36).toUpperCase();
  body.append($("<button>" + letter + "</button>"));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>A</button>




এই ইভেন্ট প্রতিনিধি দ্বারা সম্পন্ন করা হয়। ঘটনা মোড়ক-শ্রেণীর উপাদান উপর আবদ্ধ করা হবে কিন্তু নির্বাচক-শ্রেণীর উপাদান প্রতিনিধি হবে। এটা এভাবে কাজ করে.

$('.wrapper-class').on("click", '.selector-class', function() {
    // Your code here
});

বিঃদ্রঃ:

মোড়ক-শ্রেণীর উপাদান প্রাক্তন কিছু হতে পারে। নথি, শরীর বা আপনার ঢাকনা। আবর্জনা ইতিমধ্যে বিদ্যমান থাকা উচিত।




JQuery 1.7 হিসাবে আপনি jQuery.fn.on ব্যবহার করা উচিত:

$(staticAncestors).on(eventName, dynamicChild, function() {});

এর আগে , প্রস্তাবিত পদ্ধতির ব্যবহার live() :

$(selector).live( eventName, function(){} );

যাইহোক, live() কে 1.7 এর পক্ষে on() 1.7 on() এবং সম্পূর্ণভাবে 1.9 এ সরানো হয়েছে। live() স্বাক্ষর:

$(selector).live( eventName, function(){} );

... on() স্বাক্ষর on() নিম্নলিখিত সঙ্গে প্রতিস্থাপিত করা যাবে:

$(document).on( eventName, selector, function(){} );

উদাহরণস্বরূপ, যদি আপনার পৃষ্ঠাটি dosomething ক্লাস নামটির সাথে উপাদানগুলি তৈরি করে তবে আপনি ইভেন্টটির সাথে একটি পিতা-মাতার কাছে আবদ্ধ হয়ে যাবেন যা ইতিমধ্যে বিদ্যমান রয়েছে (এটি এখানে সমস্যাটির নূন্যতম বিষয়, আপনার সাথে সম্পর্কযুক্ত এমন কিছু প্রয়োজন যা আপনাকে বাঁধতে হবে। গতিশীল বিষয়বস্তু), এটি (এবং সহজতম বিকল্প) document । যদিও মনে রাখবেন document বিয়ার সবচেয়ে কার্যকর বিকল্প হতে পারে না

$(document).on('mouseover mouseout', '.dosomething', function(){
    // what you want to happen when mouseover and mouseout 
    // occurs on elements that match '.dosomething'
});

ইভেন্ট আবদ্ধ যখন উপস্থিত যে কোন অভিভাবক জরিমানা। উদাহরণ স্বরূপ

$('.buttons').on('click', 'button', function(){
    // do something here
});

প্রযোজ্য হবে

<div class="buttons">
    <!-- <button>s that are generated dynamically and added here -->
</div>



জন রেসিগ একটি ভাল বাস্তবায়ন পোস্ট করেছেন :

// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};

আপনি যদি কোনও গ্লোবাল অবজেক্ট প্রসারিত করতে না চান তবে আপনি নীচের মতো কিছু করতে পারেন, পরিবর্তে:

// Array Remove - By John Resig (MIT Licensed)
Array.remove = function(array, from, to) {
    var rest = array.slice((to || from) + 1 || array.length);
    array.length = from < 0 ? array.length + from : from;
    return array.push.apply(array, rest);
};

তবে আমি এই পোস্টটি পোস্ট করার মূল কারণ হল সেই পৃষ্ঠাটির মন্তব্যগুলিতে প্রস্তাবিত বিকল্প বাস্তবায়নের বিরুদ্ধে ব্যবহারকারীদের সতর্ক করা (ডিসেম্বর 14, 2007):

Array.prototype.remove = function(from, to){
  this.splice(from, (to=[0,from||1,++to-from][arguments.length])<0?this.length+to:to);
  return this.length;
};

এটি প্রথমে ভালভাবে কাজ করে বলে মনে হচ্ছে, তবে একটি বেদনাদায়ক প্রক্রিয়ার মাধ্যমে আমি এটি অ্যারেতে শেষ উপাদান থেকে দ্বিতীয়টি সরানোর চেষ্টা করার সময় ব্যর্থ হয়েছি। উদাহরণস্বরূপ, যদি আপনার একটি 10-উপাদান অ্যারে থাকে এবং আপনি এটির সাথে 9 ম উপাদানটি সরাতে চেষ্টা করেন:

myArray.remove(8);

আপনি একটি 8-উপাদান অ্যারের সাথে শেষ। জানি না কেন তবে আমি জন এর বাস্তব বাস্তবায়ন নিশ্চিত এই সমস্যা নেই।





javascript jquery events unobtrusive-javascript