ক্লিকে নেস্টেড উপাদানগুলিতে ইভেন্ট বুদবুদ প্রতিরোধ প্রতিক্রিয়া


114

এখানে একটি মৌলিক উপাদান। উভয়ই <ul>এবং <li>অনক্লিক ফাংশন রয়েছে। আমি কেবলমাত্র অনক্লিক অন দ্য <li>ফায়ার করতে চাই, এটি নয় <ul>। আমি কীভাবে এটি অর্জন করতে পারি?

আমি e.preventDefault (), e.stopPropagation () এর সাথে প্রায় খেলেছি, কোনও লাভ হয়নি।

class List extends React.Component {
  constructor(props) {
    super(props);
  }

  handleClick() {
    // do something
  }

  render() {

    return (
      <ul 
        onClick={(e) => {
          console.log('parent');
          this.handleClick();
        }}
      >
        <li 
          onClick={(e) => {
            console.log('child');
            // prevent default? prevent propagation?
            this.handleClick();
          }}
        >
        </li>       
      </ul>
    )
  }
}

// => parent
// => child

আমিও একই প্রশ্ন, ছিল stackoverflow.com/questions/44711549/...

উত্তর:


160

আমারো একই ইস্যু ছিল. আমি দেখেছি stopPropagation করেনি হবে। আমি তালিকা আইটেমটিকে পৃথক উপাদানগুলিতে বিভক্ত করব, যেমন:

class List extends React.Component {
  handleClick = e => {
    // do something
  }

  render() {
    return (
      <ul onClick={this.handleClick}>
        <ListItem onClick={this.handleClick}>Item</ListItem> 
      </ul>
    )
  }
}

class ListItem extends React.Component {
  handleClick = e => {
    e.stopPropagation();  //  <------ Here is the magic
    this.props.onClick();
  }

  render() {
    return (
      <li onClick={this.handleClick}>
        {this.props.children}
      </li>       
    )
  }
}

করা উচিত নয় this.props.handleClick()মধ্যে ListItemউপাদান বলে this.props.click?
ফাঁকা পৃষ্ঠ

3
স্টপপ্রোগেশন ছাড়া অন্য কোনও উপায়?
আলী সাজিদ

নেটিভ উপাদানগুলির মতো কী<Link>
সামায়ো

আপনি যদি হ্যান্ডেলক্লিকে প্যারামিটারগুলি পাস করতে চান তবে কী হবে?
মান্টিকোর

এটি কি ভুল প্রশ্নের উত্তর দেয় না? অনুষ্ঠানটি পরিচালনা করতে ওপিকে তালিকা আইটেম চেয়েছিল। সমাধানের তালিকাটি এটি পরিচালনা করে। (যদি না আমি কিছু ভুল বুঝি।)
টমাস জে রাশ

56

প্রতিক্রিয়াগুলি ইভেন্টের জন্য নথিটিতে একক ইভেন্ট শ্রোতার সাথে ইভেন্ট প্রতিনিধিদের ব্যবহার করে যা বুদবুদ, উদাহরণস্বরূপ 'ক্লিক' এর মতো, যার অর্থ প্রচার বন্ধ করা সম্ভব নয়; বাস্তব ইভেন্টটি ইতিমধ্যে আপনি প্রতিক্রিয়াতে এর সাথে ইন্টারঅ্যাক্ট করার মাধ্যমে প্রচার করেছে। প্রতিক্রিয়াটির সিন্থেটিক ইভেন্টের উপর স্টপপ্রাগেশন সম্ভব কারণ প্রতিক্রিয়াটি সিন্থেটিক ইভেন্টগুলির অভ্যন্তরীণ প্রসারণ পরিচালনা করে।

stopPropagation: function(e){
    e.stopPropagation();
    e.nativeEvent.stopImmediatePropagation();
}

সুপার দরকারী .. stopPropagation (তার নিজের উপর) সঠিকভাবে কাজ করছে না হয়
Pravin

1
এটিই আমার পক্ষে কাজ করেছিল কারণ আমি document.addEventListener('click')প্রতিক্রিয়াটির সাথে মিলিত ব্যবহার করছিonClick
ওথোথা

2
কখনও কখনও এটি কাজ নাও করতে পারে - উদাহরণস্বরূপ যদি আপনি মেটেরিয়াল-ইউআই (www.matory-ui.com) এর মতো কোনও লাইব্রেরি ব্যবহার করছেন বা আপনার হ্যান্ডলারগুলিকে অন্য উপাদানগুলির কলব্যাকে মোড়ানো করছেন। তবে আপনার নিজের কোড যদি সরাসরি হয়, ঠিক আছে!
rob2d

1
@ rob2d, সুতরাং কীভাবে ম্যাটারিয়াল-ইউআই ব্যবহার করার সাথে এটি ব্যবহার করবেন?
ইটালিক

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

9

ডোম ইভেন্টের ক্রম অনুসারে: ক্যাপচারিং বনাম বুবলিংগ

ইভেন্টগুলি কীভাবে প্রচার করে তার জন্য দুটি পর্যায়ে রয়েছে। এগুলিকে "ক্যাপচারিং" এবং "বুদবুদ" বলা হয়

               | |                                   / \
---------------| |-----------------   ---------------| |-----------------
| element1     | |                |   | element1     | |                |
|   -----------| |-----------     |   |   -----------| |-----------     |
|   |element2  \ /          |     |   |   |element2  | |          |     |
|   -------------------------     |   |   -------------------------     |
|        Event CAPTURING          |   |        Event BUBBLING           |
-----------------------------------   -----------------------------------

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

// CAPTURING event
button.addEventListener('click', handleClick, true)

// BUBBLING events
button.addEventListener('click', handleClick, false)
button.addEventListener('click', handleClick)

প্রতিক্রিয়া হিসাবে, বুদবুদ ঘটনাগুলি আপনি ডিফল্টরূপে ব্যবহার করেন।

// handleClick is a BUBBLING (synthetic) event
<button onClick={handleClick}></button>

// handleClick is a CAPTURING (synthetic) event
<button onClickCapture={handleClick}></button>

আসুন আমাদের হ্যান্ডেল ক্লিক কলব্যাকের ভিতরে একবার দেখে নিন (প্রতিক্রিয়া):

function handleClick(e) {
  // This will prevent any synthetic events from firing after this one
  e.stopPropagation()
}
function handleClick(e) {
  // This will set e.defaultPrevented to true
  // (for all synthetic events firing after this one)
  e.preventDefault()  
}

একটি বিকল্প যা আমি এখানে উল্লেখ করে দেখিনি

আপনি যদি আপনার সমস্ত ইভেন্টে e.preventDefault () কল করেন তবে আপনি কোনও ইভেন্ট ইতিমধ্যে পরিচালনা করা হয়েছে কিনা তা পরীক্ষা করে দেখতে পারেন এবং এটিকে আবার পরিচালনা করা থেকে বিরত রাখতে পারেন:

handleEvent(e) {
  if (e.defaultPrevented) return  // Exits here if event has been handled
  e.preventDefault()

  // Perform whatever you need to here.
}

সিন্থেটিক ইভেন্ট এবং নেটিভ ইভেন্টের মধ্যে পার্থক্যের জন্য প্রতিক্রিয়া ডকুমেন্টেশন দেখুন: https://reactjs.org/docs/events.html


5

এটি ১০০% আদর্শ নয়, তবে যদি propsবাচ্চাদের মধ্যে সবচেয়ে বেশি ব্যথা হয় -> শিশুদের ফ্যাশন বা একটি Context.Provider/ Context.Consumer কেবল এই উদ্দেশ্যে তৈরি করা) এবং আপনি নিজের লাইব্রেরির সাথে পরিচালনা করছেন যা এটির নিজস্ব হ্যান্ডলারটি চালিত হয় আপনার আগে, আপনি চেষ্টা করতে পারেন:

   function myHandler(e) { 
        e.persist(); 
        e.nativeEvent.stopImmediatePropagation();
        e.stopPropagation(); 
   }

আমি যা বুঝতে পারি তা থেকে, event.persistপদ্ধতিটি কোনও বস্তুকে তত্ক্ষণাত রিএ্যাক্টের SyntheticEventপুলে ফেলে দেওয়া থেকে বাধা দেয় । সুতরাং যে কারণে, eventপ্রতিক্রিয়া পাস পাস আসলে এটি পৌঁছানোর সময় দ্বারা অস্তিত্ব! নাতি-নাতনিদের ক্ষেত্রে এই ঘটনার কারণ SyntheticEventহ্যান্ডলারের জন্য প্রথমে পিতামাতার উপর নজর রাখার মাধ্যমে অভ্যন্তরীণভাবে হ্যান্ডেলের জিনিসগুলির প্রতিক্রিয়া ঘটে (বিশেষত যদি পিতামাতার কলব্যাক থাকে)।

যতক্ষণ আপনি এমন কোনও persistকিছুতে কল না করছেন যা ইভেন্টগুলি তৈরি করতে গুরুত্বপূর্ণ স্মৃতি তৈরি করে onMouseMove(এবং আপনি কোনও ধরণের কুকি ক্লিকার খেলা যেমন দাদির কুকিজের মতো তৈরি করছেন না), এটি পুরোপুরি ঠিক হওয়া উচিত!

এছাড়াও নোট: মাঝে মাঝে তাদের GitHub প্রায় পড়া থেকে, আমরা প্রতিক্রিয়া ভবিষ্যত সংস্করণ জন্য আমাদের চোখ রাখা হিসাবে তারা উচিত পারে অবশেষে এই সঙ্গে ব্যথা কিছু সমাধান হিসাবে তারা ভাঁজ উপার্জন প্রতি যাচ্ছে বলে মনে একটি কম্পাইলার / transpiler কোড প্রতিক্রিয়া।


1

আমি কাজ করতে সমস্যা ছিল event.stopPropagation()। আপনি যদি এটি করেন তবে এটিকে আপনার ক্লিক হ্যান্ডলার ফাংশনের শীর্ষে নিয়ে যাওয়ার চেষ্টা করুন, ঘটনাটি বুদবুদ হওয়া থেকে থামানোর জন্য আমার যা করা দরকার ছিল তা। ফাংশন উদাহরণ:

  toggleFilter(e) {
    e.stopPropagation(); // If moved to the end of the function, will not work
    let target = e.target;
    let i = 10; // Sanity breaker

    while(true) {
      if (--i === 0) { return; }
      if (target.classList.contains("filter")) {
        target.classList.toggle("active");
        break;
      }
      target = target.parentNode;
    }
  }

0

আপনি ইভেন্টের লক্ষ্য পরীক্ষা করে ইভেন্ট বুদবুদ এড়াতে পারেন।
উদাহরণস্বরূপ, যদি আপনি ডিভ উপাদানটিতে ক্লিক করে ইভেন্টের জন্য হ্যান্ডলারটি থাকে এবং আপনি এটি পরিচালনা করতে চান না, যখন ইনপুট ক্লিক করা হয়, আপনি কেবল event.targetআপনার হ্যান্ডলারের মধ্যে প্রবেশ করতে পারেন এবং চেক হ্যান্ডলারের উপর ভিত্তি করে সম্পাদন করা উচিত লক্ষ্য বৈশিষ্ট্য।
উদাহরণস্বরূপ আপনি পরীক্ষা করতে পারেন if (target.localName === "input") { return}
সুতরাং, এটি হ্যান্ডলার কার্যকরকরণ "এড়ানোর" উপায়


-4

এটি করার নতুন উপায়টি অনেক বেশি সহজ এবং আপনাকে কিছুটা সময় সাশ্রয় দেবে! আসল ক্লিক হ্যান্ডলারের মধ্যে কেবল ইভেন্টটি পাস করুন এবং কল করুন preventDefault();

clickHandler(e){
    e.preventDefault();
    //Your functionality here
}

3
-1; আমি এটি পরীক্ষা করেছি এবং এটি ক্লিক প্রচারের জন্য কাজ করে না। আফাইক এটি কার্যকর হবে যদি আপনি মূল লিঙ্ক কার্যকারিতা বন্ধ করে এমন লিঙ্কগুলির জন্য অনক্লিক হ্যান্ডলার চান তবে ইভেন্ট বুবলিংয়ের জন্য নয়।
জোয়েল পেল্টেন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.