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




jquery events unobtrusive-javascript (20)

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

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

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

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


Answers

আরেকটি সমাধান উপাদান তৈরি করার সময় শ্রোতা যোগ করা হয়। শরীরে শ্রোতা রাখার পরিবর্তে, আপনি যে মুহূর্তে এটি তৈরি করেছেন তার মধ্যে আপনি শ্রোতাটিকে উপাদানটিতে রাখেন:

var myElement = $('<button/>', {
    text: 'Go to Google!'
});

myElement.bind( 'click', goToGoogle);
myElement.append('body');


function goToGoogle(event){
    window.location.replace("http://www.google.com");
}

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

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

বিঃদ্রঃ:

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


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

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

ইভেন্ট হ্যান্ডলারগুলিকে লাইভ উপাদান সংযুক্ত করার জন্য jQuery এর .on() পদ্ধতিটি on() ব্যবহার করুন।

এছাড়াও সংস্করণ 1.9 .live() পদ্ধতি হিসাবে মুছে ফেলা হয়।


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

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

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

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

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

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

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

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

অথবা

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

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

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


আমি একটি 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
}


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


উপাদান এবং বদ্ধ ইভেন্ট তৈরি করার জন্য আরো নমনীয় সমাধান ( 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);

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


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

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>


যখন আপনি 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>


উপাদান স্থাপন করা হয় "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");
    });
 });

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

একক উপাদান:

$(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 ব্যবহার করছি, কিন্তু আমি জানি না তারা এটি পরিবর্তন করেছে কিনা।


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

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

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

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

.bind() পরিবর্তে .live() ব্যবহার করার চেষ্টা করুন; .live() আবদ্ধ হবে। অ্যাজ্যাক্স অনুরোধ .hover করার পরে আপনার চেকবক্সে রাখুন।


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

$(document).on("click", "selector", 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>

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

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

<!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>

একটি জাভাস্ক্রিপ্ট সমাধান সম্পর্কে কি?

একটি টুকরা ঘোষণা করুন:

var fragment = document.createDocumentFragment();

টুকরা করতে পছন্দসই উপাদান যোগ করুন:

fragment.appendChild(document.getElementById('source'));

পছন্দসই উপাদান ফাঁক যোগ করুন:

document.getElementById('destination').appendChild(fragment);

এটা দেখ.







javascript jquery events unobtrusive-javascript