নেস্টেড এনজি-ক্লিক কলগুলির মধ্যে ইভেন্টের প্রচার বাতিল করার সর্বোত্তম উপায় কী?


180

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

এইচটিএমএল:

<div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()">
    <img src="http://some_src" ng-click="nextImage()"/>
</div>

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

function OverlayCtrl($scope) {
    $scope.hideOverlay = function() {
        // Some code to hdie the overlay
    }
    $scope.nextImage = function() {
        // Some code to find and display the next image
    }
}

সমস্যাটি হ'ল এই সেটআপটি দিয়ে আপনি যদি চিত্রটিতে ক্লিক করেন তবে উভয়ই nextImage()এবং hideOverlay()ডাকা হয়। তবে আমি যা চাই তা কেবল কল nextImage()করার জন্য ।

আমি জানি আপনি nextImage()এই অনুষ্ঠানটি এভাবে ক্যাপচার এবং বাতিল করতে পারেন :

if (window.event) {
    window.event.stopPropagation();
}

... তবে আমি জানতে চাই যে এটি করার কোনও আরও ভাল অ্যাঙ্গুলারজেএস উপায় আছে যা আমাকে এই স্নিপেটের সাথে ওভারলেতে থাকা সমস্ত উপাদানগুলির উপসর্গের প্রয়োজন হবে না।


1
return falseফাংশন শেষে
জোনাথন ডি এম

1
আমি বিশ্বাস করি এটি এটাই করার উপায় onclick, না ng-click
মাইকেল শ্যাপার

উত্তর:


193

@ জোসেফসিলবার যা বলেছিলেন, বা $ ইভেন্ট অবজেক্টটিকে ng-clickকলব্যাকে পাস করুন এবং এর অভ্যন্তরে প্রচার বন্ধ করুন:

<div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()">
  <img src="http://some_src" ng-click="nextImage($event)"/>
</div>
$scope.nextImage = function($event) {
  $event.stopPropagation();
  // Some code to find and display the next image
}

8
$ ইভেন্ট.প্রিভেন্টড্যাফল্ট () ব্যবহার করুন; ইন>> 1.5
কুলকবিন

3
কুলকবিন আমি অ্যাংুলার 1.5.8 এবং। ইভেন্ট.স্টপপ্রপাগেশন () ব্যবহার করছি এখনও ভাল কাজ করে। । ইভেন্ট.প্রিভেন্টডিফল্ট () তবে কাজ করে না
হামারএনএল

1
অদ্ভুত, কারণ আমার বিপরীত পরিস্থিতি রয়েছে। স্টপপ্রোগেশন আর কাজ করে না, তবে প্রতিরোধ ডিফল্ট () করে। কেবলমাত্র পার্থক্য হ'ল আমি সরাসরি এনজি-ক্লিক করে কল করেছি। <TR NG-ক্লিক = "ctr.foo (); $ event.preventDefault ()"> ..... </ TR>
MilitelloVinx

171

ব্যবহার $event.stopPropagation():

<div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()">
    <img src="http://some_src" ng-click="nextImage(); $event.stopPropagation()" />
</div>

এখানে একটি ডেমো রয়েছে: http://plnkr.co/edit/3Pp3NFbGxy30srl8OBmQ?p= পূর্বরূপ


আমি ReferenceError: $event is not definedকনসোলে উঠি ।
সিলফেক্স

হ্যাঁ, এটি কাজ করে ... আমি যখন স্ক্র্যাচ থেকে আলাদা একটি সাধারণ সংস্করণ লিখি তখন এটিও কাজ করে। আমি এটি কীভাবে তৈরি করতে পারি তা আমার ডেভেলপমেন্ট কোডটিতে কাজ না করার চেষ্টা করছি। ডুনো: \
সিলফেক্স

@ সিলফেক্স - আপনি কি অ্যাঙ্গুলারের একটি আধুনিক সংস্করণ ব্যবহার করছেন?
জোসেফ সিলবার

হ্যাঁ - সবেমাত্র সমস্যাটি খুঁজে পেয়েছি। পরীক্ষার সময় আমি $event.stopPropagation()এমন জায়গায় রাখার চেষ্টা করেছি যেখানে এটি কাজ করে না। এটি মুছে ফেলতে ভুলে গেছেন। এমনকি যেখানে আমি এটি যেখানে কাজ করেছি সেখানে রেখেছি, এটি দ্বিতীয়বার বলা হয়েছিল যেখানে এটি হয়নি। অকার্যকর সদৃশ থেকে মুক্তি পেয়েছি এবং এটি সফল। আপনার সাহায্যের জন্য ধন্যবাদ.
cilphex

101

আমি এর জন্য একটি নির্দেশিকা ব্যবহার করার ধারণাটি পছন্দ করি:

.directive('stopEvent', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attr) {
            element.bind('click', function (e) {
                e.stopPropagation();
            });
        }
    };
 });

তারপরে নির্দেশিকাটি ব্যবহার করুন:

<div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()">
    <img src="http://some_src" ng-click="nextImage()" stop-event/>
</div>

আপনি যদি চান, আপনি এই সমস্যার সমাধানটিকে আরও সাধারণ প্রশ্নের উত্তর দেওয়ার মতো তৈরি করতে পারেন: https://stackoverflow.com/a/14547223/347216


2
যদি আপনার উপাদানটি ডিওএম থেকে গতিশীলভাবে যুক্ত / সরানো হয় তবে '$ ধ্বংস' ইভেন্টের জন্য আপনার উপাদানটি দেখতে ভুলবেন না যাতে আপনি হ্যান্ডলারটিকে আনবাইন্ড করতে পারেন। উদাহরণস্বরূপ, এলিমেন্ট.অন ('$ ধ্বংস', ফাংশন () {/ * এখানে আনবাইন্ডিং করুন * /});
broc.seib

হয় stop-eventএকটি HTML অ্যাট্রিবিউট? আমি এটি মজিলা বিকাশকারী নেটওয়ার্ক বা অন্য কোথাও খুঁজে পাইনি।
এহতেশ চৌধুরী চৌদ্দ

3
@ এহতেশচৌধুরী - উপরের জেএস স্নিপেটে আমি তৈরি নতুন নির্দেশিকা "স্টপ-ইভেন্ট"। এখানে নির্দেশাবলী ঘোষণা এবং ব্যবহার সম্পর্কে আরও দেখুন: ডকস.আঙ্গুলারজেএস.আর
ডেভিড

চমৎকার সমাধান! আমি প্রকৃতপক্ষে angular-eat-eventবোভারের উপর নির্দেশিকা নিবন্ধভুক্ত করেছি , যা একইভাবে কাজ করে!
gion_13

এটি কাজ করছে বলে মনে হচ্ছে না, নির্দেশের আগে এনজি-ক্লিক মূল্যায়ন করে। সুতরাং আমি কার্যকর করতে বাধা দিতে পারি তবে অন্যভাবে নয়।
রাফায়েল

31

কখনও কখনও, এটি এটি করার জন্য সর্বাধিক বোধ করতে পারে:

<widget ng-click="myClickHandler(); $event.stopPropagation()"/>

আমি এটি এইভাবেই বেছে নিয়েছি কারণ myClickHandler()এটি ব্যবহৃত অন্যান্য অনেক জায়গায় ইভেন্টের প্রচার বন্ধ করতে চাইনি ।

অবশ্যই, আমি হ্যান্ডলারের ফাংশনে একটি বুলিয়ান প্যারামিটার যুক্ত করতে পারতাম, তবে stopPropagation()কেবলমাত্র এর চেয়ে অনেক বেশি অর্থবহ true


2
আমি এই সংস্করণটি সর্বদা পছন্দ করি, মনে হয় যে উপাদানটির বাসা
বাঁধার জন্য

আমাকে $event.stopPropagation()অভ্যন্তরীণ উপাদানগুলিতে যুক্ত করতে হয়েছিল।
কিশোর পওয়ার

@ কিশোরপওয়ার: কেন? উত্তরে আমি যেভাবে করেছি তা কি আপনার পক্ষে কার্যকর হয়নি? যদি এটি না হয়, তবে এটি আমাদের পক্ষে ভাল হবে যে এটি কৌণিকর কাজ করার পদ্ধতিতে বা আপনার কোডে কোনও সমস্যার কারণে হয়েছে whether
মাইকেল শ্যাপার

@ মিশেলশেপার আমি উপাদান checkboxআবদ্ধ করছি div। আমার div12 টি কলাম নিচ্ছে এবং checkbox3 টি কলাম বলছে। আমি একটি ফাংশন কল করতে চেয়েছিলেন Aক্লিক উপর divএবং ফাংশন Bএর ক্লিক checkbox। সুতরাং যখন আমি checkboxউভয় ফাংশন ক্লিক করা ছিল অনুরোধ করা হচ্ছে। আমি যুক্ত ng-click="$event.stopPropagation()"করার পরে checkbox, আমি কেবল ফাংশন Bচালিত হয়েছি ।
কিশোর

@ কিশোরপওয়ার: আহ। হ্যাঁ, আমি এটি প্রত্যাশা করব এবং প্রকৃতপক্ষে, মূল বিষয়টি stopPropagation()হল ইভেন্টটিকে পিতামাতার উপাদানগুলিতে প্রচার বন্ধ করা। আমি নই আপনি কি নিশ্চিতরূপে কিভাবে কল করছেন Bযেহেতু এটা নিদির্ষ্ট না ng-click, কিন্তু উত্তর বিন্দু আপনি এটা করতে পারেন যে: <checkbox ng-click="B(); $event.stopPropagation()">। আপনাকে stopPropagation()ফাংশনটি অন্তর্ভুক্ত করতে হবে না B
মাইকেল শ্যাপার

7

এটি আমার পক্ষে কাজ করে:

<a href="" ng-click="doSomething($event)">Action</a>

this.doSomething = function($event) {
  $event.stopPropagation();
  $event.preventDefault();
};

আমি সিআরটিএল কী টিপে বা না চাপেই মাউস ক্লিকগুলি পরিচালনা করতে চেয়েছিলাম। ব্রাউজারে এইচটিএমএল উপাদানগুলির নির্বাচন (এবং হাইলাইট) বন্ধ করতে (ব্যবহারকারী আমার ক্ষেত্রে 11) ব্যবহারকারী যখন Ctrl কী চেপে ধরে রেখে বিভিন্ন আইটেম ক্লিক করেন, আমাকে এনজি-মাউজডাউন ইভেন্টটি ব্যবহার করতে হয়েছিল এবং $ ইভেন্টের মাধ্যমে ডিফল্ট আচরণ বাতিল করতে হয়েছিল .preventDefault ()
pholpar

4

আপনি যদি সমস্ত লিঙ্কগুলিতে স্টপ প্রচার যুক্ত করতে না চান তবে এটি কাজ করে। আরও কিছুটা স্কেলেবল

$scope.hideOverlay( $event ){

   // only hide the overlay if we click on the actual div
   if( $event.target.className.indexOf('overlay') ) 
      // hide overlay logic

}

2
এই সমাধানটি প্রদত্ত উদাহরণের জন্য কাজ করে (যা দুর্দান্ত!) তবে বাইরের ডিভিতে href / ng- ক্লিকের পূর্বে n বা আরও বেশি নেস্টেড উপাদান থাকলে এটি কাজ করে না। তারপরে যখন হাইডওভারলে () কলব্যাক আহ্বান করা হয় তখন লক্ষ্যটি নেস্টেড উপাদানগুলির মধ্যে একটি এবং কোনও এনজি-ক্লিক নির্দেশের বহিরাগত উপাদান নয়। বাসাবাড়িত উপাদানগুলি হ্যান্ডেল করার জন্য, বাবা-মাকে পেতে এবং প্রথম ক্লিকযোগ্য (ক, এনজি-ক্লিক, ইত্যাদি) পিতামাতার ওভারলে ক্লাস ছিল কিনা তা দেখতে jquery ব্যবহার করতে পারে তবে তা দেখতে কিছুটা জটিল দেখা যাচ্ছে ...
আমির

কনসোল.লগ ("আলু-ওভারলে" .indexOf ("ওভারলে")! = -1); console.log (/ \ boverlay \ b হল / g.test ( "potatooverlay"));

event.target.classList.indexOf('overlay')
কৌণিকটি

0

আপনি যদি আপনার টেম্পলেটটির মূল উপাদানটিতে এনজি-ক্লিক = "$ ইভেন্ট.স্টপপ্রপাগেশন" সন্নিবেশ করেন তবে গাছটি বুদবুদ হওয়ার সাথে সাথে স্টপপ্রোগেশনটি ধরা পড়বে, সুতরাং আপনার সম্পূর্ণ টেম্পলেটটির জন্য আপনাকে কেবল এটি একবার লিখতে হবে।


0

আপনি উপরে অন্য একটি নির্দেশিকা নিবন্ধন করতে পারেন ng-clickযার উপরে ডিফল্ট আচরণের সংশোধন ng-clickকরে ইভেন্টের প্রচার বন্ধ করে দেয়। এইভাবে আপনাকে $event.stopPropagationহাত দিয়ে যুক্ত করতে হবে না ।

app.directive('ngClick', function() {
    return {
        restrict: 'A',
        compile: function($element, attr) {
            return function(scope, element, attr) {
                element.on('click', function(event) {
                    event.stopPropagation();
                });
            };
        }
    }
});

0
<div ng-click="methodName(event)"></div>

নিয়ামক ব্যবহার

$scope.methodName = function(event) { 
    event.stopPropagation();
}

এটি করার পদ্ধতিতে প্রথমে ইভেন্টটি প্রেরণ করুন
দিনেশ জৈন

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