সিউডো-এলিমেন্টে কেবল ক্লিক ইভেন্টটি সনাক্ত করুন


213

আমার কোডটি হ'ল:

p {
    position: relative;
    background-color: blue;
}

p:before {
    content: '';
    position: absolute;
    left:100%;
    width: 10px;
    height: 100%;
    background-color: red;
}

দয়া করে এই ঝাঁকুনি দেখুন: http://jsfiddle.net/ZWw3Z/5/

আমি কেবল সিউডো-এলিমেন্টে (লাল বিট) ক্লিক ক্লিক করতে চাই। অর্থাত, আমি চাই না যে ক্লিকের ইভেন্টটি নীল বিটের উপরে ট্রিগার করা হোক।


1
ক্লিক করা পোস্টগুলি কীভাবে পরীক্ষা করবেন? stackoverflow.com/questions/3234977/...

এখানে আমার আগের পোস্ট করা সমাধানটি পড়ুন ।
আমর

সম্ভবত এখানে একটি ভাল কাজ ।
রেজা মামুন

উত্তর:


218

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

যদি আপনার অবশ্যই লাল অঞ্চলে ক্লিক হ্যান্ডলার থাকে তবে আপনাকে একটি শিশু উপাদান তৈরি করতে হবে, যেমন span, এটি খোলার <p>ট্যাগের ঠিক পরে রাখে , p spanপরিবর্তে শৈলী প্রয়োগ করতে p:beforeএবং এটি আবদ্ধ হয়।


108
দেখে মনে হয় যে আধুনিক ব্রাউজারগুলিতে pointer-eventsউপাদানটি নিজেই এবং এর সিউডো উপাদানগুলির জন্য বিভিন্ন মান সহ সম্ভব : jsfiddle.net/ZWw3Z/70
Ilya Streltsyn

5
@ ইলিয়া স্ট্র্লটসিন আশ্চর্যজনক - 'সঠিক' উত্তর নয় (আপনার যদি উপাদানটিতে ক্লিক করার দরকার হয় তবে কাজ করবে না) তবে
ডিভসের

pointer-eventsইলিয়া পোস্ট করা jsfiddel অনুসারে, IE9 এর জন্য কৌতুকটি করতে দেখাবেন না।
ব্যবহারকারী 39323274

@ ব্যবহারকারী 39323274: আই 99 এসভিজির বাইরে পয়েন্টার-ইভেন্টগুলিকে সমর্থন করে না।
বোল্টক্লক

1
@ তিভ না, এই পৃষ্ঠায় পুরো লাইনটি লিঙ্ক থেকে বাম এবং ডান উভয়ই ক্লিকযোগ্য। কেবলমাত্র লিঙ্কটিতেই আলাদা ক্লিকের হ্যান্ডলার রয়েছে, সুতরাং এটি ক্লিক করলে ভাঁজ / ফোল্ডিং সাবট্রি ট্রিগার হয় না।
ইলিয়া স্ট্রেলটসিন

131

আসলে, এটা সম্ভব। ক্লিক করা অবস্থানটি উপাদানটির বাইরে ছিল কিনা তা আপনি পরীক্ষা করতে পারেন, যেহেতু এটি তখনই ঘটবে ::beforeবা ::afterক্লিক করা হয়েছিল।

এই উদাহরণটি কেবলমাত্র উপাদানটিকে ডানদিকে যাচাই করে তবে এটি আপনার ক্ষেত্রে কাজ করা উচিত।

span = document.querySelector('span');

span.addEventListener('click', function (e) {
    if (e.offsetX > span.offsetWidth) {
        span.className = 'c2';
    } else {
        span.className = 'c1';
    }
});
div { margin: 20px; }
span:after { content: 'AFTER'; position: absolute; }

span.c1 { background: yellow; }
span.c2:after { background: yellow; }
<div><span>ELEMENT</span></div>

JSFiddle


1
এটি আমার পক্ষে কাজ করে না, আমি যে কোনও একটিতে ক্লিক করলে পাঠ্যটি হাইলাইট হয়। ফায়ারফক্স ব্যবহার করা, যদি এটি গুরুত্বপূর্ণ (না হওয়া উচিত)।
ফ্ল্যাটার

2
ফায়ারফক্সের জন্য: jsfiddle.net/wC2p7/16 । যদি নেস্টেড উপাদানগুলির সাথে কাজ করা হয় তবে আপনার নেস্টেড অফসেটগুলি যথাযথ হিসাবে গণনা করতে হবে (যেমন: jQuery: $ (e.target)। অফসেট ()। বাম)
bebbi

1
ভয়ঙ্কর মানুষ ধন্যবাদ, এটি কার্যকর। তবে ফায়ারফক্স এবং অন্যান্য মান মেনে চলতে সক্ষম ব্রাউজারগুলিতে, এই ব্রাউজারগুলির সম্পত্তি নেই বলে আপনার উপরের মাউসকে :afterপরীক্ষা করে if (e.clientX > span.offsetLeft + span.offsetHeight)দেখতে হবে কিনা e.offsetX। ফিডল: jsfiddle.net/Noitidart/wC2p7/18
Noitidart

5
এমনকি কুলার যদি $('a:after').on('click', fn)
জিকিউরির

25
উপাদানটির অভ্যন্তরে অবস্থান করা থাকলে ::beforeবা ::afterএটি আসলে কাজ করবে না ।
ল্যাকনবাস

74

উপর আধুনিক ব্রাউজারে আপনি পয়েন্টার-ঘটনা CSS সম্পত্তি দিয়ে চেষ্টা করতে পারেন (কিন্তু এটি পিতা বা মাতা নোডের উপর মাউস ঘটনা সনাক্ত করতে অসম্ভবতা বাড়ে):

p {
    position: relative;
    background-color: blue;
    color:#ffffff;
    padding:0px 10px;
    pointer-events:none;
}
p::before {
    content: attr(data-before);
    margin-left:-10px;
    margin-right:10px;
    position: relative;
    background-color: red;
    padding:0px 10px;
    pointer-events:auto;
}

ইভেন্টের লক্ষ্যটি যখন আপনার "পি" উপাদান হয়, আপনি জানেন যে এটি আপনার "পি: পূর্বে"।

আপনি যদি এখনও প্রধান পিতে মাউস ইভেন্টগুলি সনাক্ত করতে চান তবে আপনি আপনার HTML কাঠামোটি সংশোধন করার সম্ভাবনাটি বিবেচনা করতে পারেন। আপনি একটি স্প্যান যোগ করতে পারেন ট্যাগ এবং নিম্নলিখিত শৈলী :

p span {
    background:#393;
    padding:0px 10px;
    pointer-events:auto;
}

ইভেন্টের লক্ষ্যগুলি এখন "স্প্যান" এবং "পি: পূর্বে" উভয় উপাদান both

Jquery ছাড়া উদাহরণ: http://jsfiddle.net/2nsptvcu/

Jquery সঙ্গে উদাহরণ: http://jsfiddle.net/0vygmnnb/

এখানে পয়েন্টার-ইভেন্টগুলিকে সমর্থনকারী ব্রাউজারগুলির তালিকা রয়েছে: http://caniuse.com/#feat=pointer-events


পিতামাতার নোড কেন জানি না। আপনি কি বলছেন যে আমি যদি .box এর মতো কিছুতে ইভেন্ট ক্লিক করি: এর আগে, তত্কালীন .বক্স কোনও ক্লিক সনাক্ত করতে পারে না?
অত্যন্ত শ্রদ্ধেয় স্যার

এটি আংশিক সত্য: আপনার সিএসএসে .box {পয়েন্টার-ইভেন্টগুলি: কিছুই নয়;} .box: এর আগে {পয়েন্টার-ইভেন্টস: অটো;। এর পরে কেবলমাত্র উপাদান যা এখনও ইভেন্টগুলিকে সমর্থন করে তা হল p: এর আগে। যাইহোক মনে রাখবেন যে জেএস আপনাকে .box থেকে মূল .box উপাদানটি ফিরিয়ে দেবে: এর আগে সত্যই ডমটিতে বাস না করে।
ফ্যাসোইউ

9

আমার উত্তরটি পৃষ্ঠার একটি নির্দিষ্ট ক্ষেত্রটি ক্লিক করতে চায় এমন ব্যক্তির পক্ষে কাজ করবে। এটি আমার জন্য আমার জন্য কাজ করেছে একেবারে অবস্থানযুক্ত: পরে after

এই ধন্যবাদ নিবন্ধ , আমি (jQuery সঙ্গে) আমি ব্যবহার করতে পারেন উপলব্ধি e.pageYএবং e.pageXসম্পর্কে উদ্বেজক পরিবর্তে e.offsetY/Xএবংe.clientY/X ব্রাউজারগুলির মধ্যে ইস্যু ।

আমার বিচার এবং ত্রুটির মধ্য দিয়ে, আমি jQuery ইভেন্ট অবজেক্টে ক্লায়েন্টএক্স এবং ক্লায়েন্টওয়াই মাউস স্থানাঙ্কগুলি ব্যবহার করতে শুরু করেছি। এই সমন্বয়গুলি ব্রাউজারের ভিউ পোর্টের উপরের-বাম কোণে আপেক্ষিকভাবে মাউসের এক্স এবং ওয়াই অফসেট দিয়েছিল। আমি যখন কার্ল সুইডেনবার্গ এবং জনাথন শেফারের জিকুয়েরি ১.৪ রেফারেন্স গাইডটি পড়ছিলাম, তবে আমি দেখেছি তারা প্রায়শই পেজএক্সএক্স এবং পেজওয়াই স্থানাঙ্ককে নির্দেশ করে। আপডেট করা jQuery ডকুমেন্টেশন চেক করার পরে, আমি দেখেছি যে এগুলি jQuery দ্বারা মানীকৃত স্থানাঙ্ক ছিল; এবং, আমি দেখেছি তারা পুরো ডকুমেন্টের তুলনায় আমাকে মাউসের এক্স এবং ওয়াই অফসেট দিয়েছে (কেবল দেখার পোর্ট নয়)।

আমি এই event.pageYধারণাটি পছন্দ করেছি কারণ এটি নথির সাথে সম্পর্কিত হিসাবে এটি সর্বদা একই থাকত । আমি এটি আমার সাথে তুলনা করতে পারি: অফসেট () ব্যবহার করে পরবর্তী পিতামাতার উপাদানটি, যা ডকুমেন্টের সাথে সম্পর্কিত তার এক্স এবং ওয়াইও সরবরাহ করে।

অতএব, আমি পুরো পৃষ্ঠায় একটি "ক্লিকযোগ্য" অঞ্চল নিয়ে আসতে পারি যা কখনই পরিবর্তন হয় না।


কোডেপেনে আমার ডেমোটি এখানে ।


অথবা কোডেপেনের জন্য খুব অলস হলে এখানে জেএস রয়েছে:

* আমি কেবলমাত্র আমার উদাহরণের জন্য ওয়াই মানগুলির যত্ন নিই।

var box = $('.box');
// clickable range - never changes
var max = box.offset().top + box.outerHeight();
var min = max - 30; // 30 is the height of the :after

var checkRange = function(y) {
  return (y >= min && y <= max);
}

box.click(function(e){
  if ( checkRange(e.pageY) ) {
    // do click action
    box.toggleClass('toggle');
  }
});

6

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

$('#element').click(function (e) {
        if (e.offsetX > e.target.offsetLeft) {
            // click on element
        }
         else{
           // click on ::before element
       }
});

6

সংক্ষিপ্ত উত্তর:

আমি এটা করেছি। আমি সেখানে সমস্ত অল্প লোকের জন্য গতিশীল ব্যবহারের জন্য একটি ফাংশন লিখেছি ...

পৃষ্ঠায় প্রদর্শিত হয় যা কাজ উদাহরণ

কনসোলে লগিংয়ের উদাহরণ কাজ

দীর্ঘ উত্তর:

... তবুও করেছে।

এটি করতে আমার কিছুটা সময় লেগেছে, যেহেতু কোনও psueo উপাদানটি পৃষ্ঠায় নেই। উপরের উত্তরগুলির কয়েকটি কয়েকটি পরিস্থিতিতে দৃশ্যের সাথে কাজ করে, তারা সমস্তই গতিশীল হতে পারে এবং এমন দৃশ্যে কাজ করতে ব্যর্থ হয় যেখানে কোনও উপাদান আকার এবং পজিশনে উভয়ই অপ্রত্যাশিত (যেমন প্যারেন্ট উপাদানগুলির একটি অংশকে ছাড়িয়ে নিখুঁত অবস্থানযুক্ত উপাদান)। আমার না।

ব্যবহার:

//some element selector and a click event...plain js works here too
$("div").click(function() {
    //returns an object {before: true/false, after: true/false}
    psuedoClick(this);

    //returns true/false
    psuedoClick(this).before;

    //returns true/false
    psuedoClick(this).after;

});

কিভাবে এটা কাজ করে:

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

এটি তখন মাউসের অবস্থানের সাথে তুলনা করে। যতক্ষণ না মাউস সদ্য নির্মিত ভেরিয়েবলের পরিসীমাতে থাকে ততক্ষণ এটি সত্য হয়ে যায়।

বিঃদ্রঃ:

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

কোড:

function psuedoClick(parentElem) {

    var beforeClicked,
      afterClicked;

  var parentLeft = parseInt(parentElem.getBoundingClientRect().left, 10),
      parentTop = parseInt(parentElem.getBoundingClientRect().top, 10);

  var parentWidth = parseInt(window.getComputedStyle(parentElem).width, 10),
      parentHeight = parseInt(window.getComputedStyle(parentElem).height, 10);

  var before = window.getComputedStyle(parentElem, ':before');

  var beforeStart = parentLeft + (parseInt(before.getPropertyValue("left"), 10)),
      beforeEnd = beforeStart + parseInt(before.width, 10);

  var beforeYStart = parentTop + (parseInt(before.getPropertyValue("top"), 10)),
      beforeYEnd = beforeYStart + parseInt(before.height, 10);

  var after = window.getComputedStyle(parentElem, ':after');

  var afterStart = parentLeft + (parseInt(after.getPropertyValue("left"), 10)),
      afterEnd = afterStart + parseInt(after.width, 10);

  var afterYStart = parentTop + (parseInt(after.getPropertyValue("top"), 10)),
      afterYEnd = afterYStart + parseInt(after.height, 10);

  var mouseX = event.clientX,
      mouseY = event.clientY;

  beforeClicked = (mouseX >= beforeStart && mouseX <= beforeEnd && mouseY >= beforeYStart && mouseY <= beforeYEnd ? true : false);

  afterClicked = (mouseX >= afterStart && mouseX <= afterEnd && mouseY >= afterYStart && mouseY <= afterYEnd ? true : false);

  return {
    "before" : beforeClicked,
    "after"  : afterClicked

  };      

}

সহায়তা:

আমি জানি না .... দেখে মনে হচ্ছে যেমন বোবা এবং মাঝে মাঝে একটি গুণিত মান হিসাবে অটো ফিরতে পছন্দ করে। আইটি সমস্ত ব্রাউজারগুলিতে কাজ করতে দেখায় যদি ডায়মেন্সগুলি সিএসএসে সেট করা থাকে। সুতরাং ... আপনার উচ্চতর এবং প্রস্থকে আপনার প্রিয়চু উপাদানগুলিতে সেট করুন এবং কেবল তাদের উপরের এবং বামে সরান। আমি এগুলিকে এমন জিনিসগুলিতে ব্যবহার করার পরামর্শ দিচ্ছি যাতে এটি কাজ না করে আপনি ঠিক okay একটি অ্যানিমেশন বা কিছু। ক্রোম যথারীতি কাজ করে ...


eventপ্রতিবার কোনও ইভেন্ট বন্ধ হওয়ার পরে ইভেন্ট হ্যান্ডলার ফাংশনটির মধ্য দিয়ে যায়। ক্লিক বা টাইপ পছন্দ। যখন আমরা .click()ফাংশনটি ব্যবহার করি , আমরা ক্লিক ইভেন্টটির জন্য অপেক্ষা করি। আমরা .click(function(e){...})ইভেন্টটিকে নির্দিষ্ট করে বলতে এবং বলতে পারি eতবে এটি কেবল ব্যবহারে গ্রহণযোগ্য event

3
পিইইইউডো, পিএসইও না!
বিজিকলপ

উপরের কোডটি কাজ করে না, কারণ eventএটি সংজ্ঞায়িত।
সেবাস্তিয়ান জার্টনার

@ সেবাস্তিয়ানজার্টনার - ইভেন্ট একটি কীওয়ার্ড। এটি ব্যবহারকারী যখন কিছু করে। আমি আপনার মন্তব্যের উপরে এই দুটি মন্তব্যকে আক্ষরিকভাবে ব্যাখ্যা করেছি। যখন ব্যবহারকারী পৃষ্ঠার সাথে ইন্টারঅ্যাক্ট করেন, একটি ইভেন্ট বন্ধ করা হয় (বেশিরভাগ ক্ষেত্রে)। ইভেন্ট হ'ল ইভেন্ট শ্রোতার কাছ থেকে আসা একটি কীওয়ার্ড ".ক্লিক ()"। যদি কোনও বিকাশকারী ইভেন্টের জন্য আলাদা নাম ব্যবহার করতে চান, তবে তারা এটি ইভেন্টের শ্রোতার কাছে ".ক্লিক (ই)" এর মতো সেট আপ করতে পারেন যা এটি দেখার আরও সাধারণ উপায়। তবুও .... যদিও উপরে আমার একটি লিঙ্ক কাজ করছে, আমি এটিতে আরও স্পষ্ট এবং কনসোলে লগ না করে বরং অভাবীদের জন্য পৃষ্ঠায় যুক্ত করব।

আমার উল্লেখ করা উচিত ছিল যে এটি ফায়ারফক্সে কাজ করে না, কারণ সেখানে eventসংজ্ঞায়িত রয়েছে। যদিও এটি ক্রোম এবং এজ এ কাজ করে।
সেবাস্তিয়ান জার্টনার

2

ক্লিকযোগ্য অঞ্চল সীমাবদ্ধ করতে ক্লিক ইভেন্টে শর্ত যুক্ত করুন।

    $('#thing').click(function(e) {
       if (e.clientX > $(this).offset().left + 90 &&
             e.clientY < $(this).offset().top + 10) {
                 // action when clicking on after-element
                 // your code here
       }
     });

ডেমো


1

এটি ফ্যাসোইউ সর্বশেষ CSS3 এবং জেএস ES6 সহ উত্তর সম্পাদনা করেছে

JQuery ব্যবহার না করে সম্পাদিত ডেমো

কোডের সবচেয়ে সংক্ষিপ্ত উদাহরণ:

<p><span>Some text</span></p>
p {
    position: relative;
    pointer-events: none;
}
p::before {
    content: "";
    position: absolute;
    pointer-events: auto;
}
p span {
    display: contents;
    pointer-events: auto;
}
const all_p = Array.from(document.querySelectorAll('p'));

for (let p of all_p) {
    p.addEventListener("click", listener, false);
};

ব্যাখ্যা:

pointer-eventsঘটনা নিয়ন্ত্রণ সনাক্তকরণ, লক্ষ্য থেকে ইভেন্টগুলি গ্রহণ সরানোর কিন্তু সিউডো-উপাদান থেকে পেয়ে ক্লিক করতে সম্ভব ::beforeএবং ::afterএবং আপনি সবসময় জানবে, আপনি যা সিউডো-উপাদান উপর বেশী ক্লিক করে তবে যদি এখনও ক্লিক করতে হবে, আপনি সেই সমস্ত সামগ্রীগুলি করা নেস্টেড উপাদানগুলিতে ( spanউদাহরণস্বরূপ), তবে আমরা কোনও অতিরিক্ত শৈলী প্রয়োগ করতে চাই না, display: contents;খুব সহজ সমাধান হয়ে উঠি এবং এটি বেশিরভাগ ব্রাউজার দ্বারা সমর্থিত । pointer-events: none;ইতিমধ্যে মূল পোস্টে উল্লিখিত হিসাবে ব্যাপকভাবে সমর্থিত

জাভাস্ক্রিপ্ট অংশটি ব্যাপকভাবে সমর্থিত Array.fromএবং for...ofতবে কোডগুলিতে তাদের ব্যবহার করার প্রয়োজন নেই।


0

এই উত্তরগুলির কোনওটিই নির্ভরযোগ্য নয়, এবং আমার পক্ষে আরও নির্ভরযোগ্য হবে না।

গুহাগুলি একদিকে, আপনি যদি ভাগ্যবান দৃশ্যে পৌঁছে যান যেখানে আপনি যে উপাদানটি ক্লিক করার চেষ্টা করছেন তার প্যাডিং নেই (যেমন উপাদানটির "অভ্যন্তরীণ" সমস্ত স্থান উপ-উপাদান দ্বারা সম্পূর্ণভাবে আবৃত) তবে আপনি ধারকটির বিপরীতে ক্লিক ইভেন্টের লক্ষ্যটি পরীক্ষা করতে পারে। যদি এটি মেলে, এর অর্থ আপনি মৌলটির আগে বা: পরে ক্লিক করেছেন:

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


-2

না, তবে আপনি এটি করতে পারেন

এইচটিএমএল ফাইলটিতে এই বিভাগটি যুক্ত করুন

<div class="arrow">
</div>

CSS এ আপনি এটি করতে পারেন

p div.arrow {
content: '';
position: absolute;
left:100%;
width: 10px;
height: 100%;
background-color: red;

} আশা করি এটা তোমাকে সাহায্য করবে

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