केवल छद्म तत्व पर क्लिक घटना का पता लगाएं


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
@ इल्या स्ट्रेल्टसिन अद्भुत - 'सही' उत्तर नहीं (काम नहीं करेगा यदि आपको तत्व पर क्लिक करने की आवश्यकता है), लेकिन divs पर 'क्लोज बटन' के लिए शानदार ढंग से काम करता है
RozzA

pointer-eventsआईईएल द्वारा पोस्ट किए गए jsfiddel के अनुसार, IE9 के लिए ट्रिक करते नहीं दिखाई देते।
14:39 बजे user393274

@ user393274: IE9 SVG के बाहर सूचक-घटनाओं का समर्थन नहीं करता है।
BoltClock

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: $ (eararget) .offset () छोड़ दिया)
bebbi

1
बहुत बढ़िया आदमी धन्यवाद, यह काम करता है। लेकिन फ़ायरफ़ॉक्स और अन्य मानकों के अनुरूप ब्राउज़र, परीक्षण के लिए अगर :afterआप पर माउस को जांचना है if (e.clientX > span.offsetLeft + span.offsetHeight)क्योंकि इन ब्राउज़रों के पास e.offsetXसंपत्ति नहीं है ।
फिडेल

5
यहां तक ​​कि कूलर भी होगा यदि jQuery ने समर्थन करने का फैसला किया है, $('a:after').on('click', fn)लेकिन मैं वास्तव में ऐसा नहीं देख रहा हूं: पी
लिनुस अननेबाक

25
यह वास्तव में काम नहीं करेगा ::beforeया यदि ::afterतत्व के अंदर स्थित है।
लैकोनाबस lac

74

पर आधुनिक ब्राउज़रों आप सूचक-घटनाओं सीएसएस संपत्ति के साथ की कोशिश कर सकते (लेकिन यह माता पिता के नोड पर माउस घटनाओं का पता लगाने के असंभव की ओर जाता है):

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

घटना लक्ष्य अब "स्पान" और "पी: दोनों" तत्वों से पहले हैं।

Jquery के बिना उदाहरण: http://jsfiddle.net/2nsptvcu/

Jquery के साथ उदाहरण: http://jsfiddle.net/0vygmnnb/

यहां संकेतक-घटनाओं का समर्थन करने वाले ब्राउज़रों की सूची दी गई है: http://caniuse.com/#feat=pointer-events


मुझे नहीं पता कि मूल नोड क्यों है। क्या आप यह कह रहे हैं कि अगर मैं कुछ .box: जैसी घटना पर क्लिक करता हूँ, तो पहले, .box किसी भी क्लिक का पता नहीं लगा सकता है?
सबसे आदरणीय सर

यह आंशिक रूप से सच है: यदि आपके सीएसएस में कुछ .box {पॉइंटर-ईवेंट्स: कोई नहीं;} ;बॉक्स: {पॉइंटर-इवेंट्स: ऑटो;} से पहले है, तो एकमात्र एलीमेंट जो अभी भी इवेंट्स को सपोर्ट करता है, पी: इससे पहले। वैसे भी याद रखें कि js आपको .box के बाद से मुख्य .box तत्व वापस दे देगा: इससे पहले कि वास्तव में DOM में नहीं रहता है।
फासोउ

9

मेरा उत्तर पृष्ठ के एक निश्चित क्षेत्र पर क्लिक करने के इच्छुक किसी भी व्यक्ति के लिए काम करेगा। यह मेरे लिए मेरे पर काम किया बिल्कुल : के बाद

इस लेख के लिए धन्यवाद , मुझे एहसास हुआ (jQuery के साथ) मैं उपयोग कर सकता हूं e.pageYऔर e.pageXइसके बजाय ब्राउज़र के बीच के बारे में e.offsetY/Xऔर e.clientY/Xसमस्या की चिंता कर सकता हूं ।

अपने परीक्षण और त्रुटि के माध्यम से, मैंने jQuery इवेंट ऑब्जेक्ट में clientX और clientY माउस निर्देशांक का उपयोग करना शुरू कर दिया। इन निर्देशांकों ने मुझे ब्राउज़र के व्यू पोर्ट के ऊपरी-बाएँ कोने के सापेक्ष माउस का X और Y ऑफसेट दिया। जैसा कि मैं कार्ल स्वेडबर्ग और जोनाथन चैफर द्वारा jQuery 1.4 संदर्भ गाइड पढ़ रहा था, हालांकि, मैंने देखा कि वे अक्सर पेजएक्स और पेजवाई निर्देशांक के लिए संदर्भित होते हैं। अपडेट किए गए jQuery प्रलेखन की जाँच करने के बाद, मैंने देखा कि ये jQuery द्वारा मानकीकृत निर्देशांक थे; और, मैंने देखा कि उन्होंने मुझे पूरे दस्तावेज़ (न सिर्फ व्यू पोर्ट) के सापेक्ष माउस के एक्स और वाई ऑफसेट दिए।

मुझे यह event.pageYविचार पसंद आया क्योंकि यह हमेशा वैसा ही रहेगा, जैसा कि दस्तावेज के सापेक्ष था । मैं इसकी तुलना अपने से कर सकता हूं: ऑफ़सेट () का उपयोग करने वाले मूल तत्व के बाद, जो दस्तावेज़ के सापेक्ष अपना X और Y भी लौटाता है।

इसलिए, मैं पूरे पृष्ठ पर "क्लिक करने योग्य" क्षेत्र की एक श्रृंखला के साथ आ सकता हूं जो कभी नहीं बदलता है।


यहाँ कोडपैन पर मेरा डेमो है


या यदि कोडपेन के लिए बहुत आलसी है, तो यहाँ JS है:

* मैं केवल अपने उदाहरण के लिए वाई मूल्यों के बारे में परवाह करता था।

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

संक्षिप्त जवाब:

मैंने यह किया। मैंने सभी छोटे लोगों के लिए गतिशील उपयोग के लिए एक समारोह लिखा है ...

कार्य उदाहरण जो पृष्ठ पर प्रदर्शित होता है

कंसोल के लिए लॉगिंग कार्य उदाहरण

लंबा जवाब:

... फिर भी किया।

मुझे ऐसा करने में थोड़ी देर लगी, क्योंकि पृष्ठ पर वास्तव में कोई प्यूसीडो तत्व नहीं है। हालांकि कुछ उत्तर कुछ परिदृश्यों में काम करते हैं, वे सभी गतिशील होने में विफल होते हैं और एक परिदृश्य में काम करते हैं जिसमें एक तत्व दोनों आकार और स्थिति में अप्रत्याशित होता है (जैसे कि मूल तत्व के एक हिस्से को ओवरले करने वाले निरपेक्ष तैनात तत्व)। मेरा नहीं है।

उपयोग:

//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;

});

यह काम किस प्रकार करता है:

यह मूल तत्व की ऊँचाई, चौड़ाई, शीर्ष और बाईं स्थिति (खिड़की के किनारे से दूर स्थिति के आधार पर) पकड़ लेता है और ऊँचाई, चौड़ाई, शीर्ष और बाएँ पदों को पकड़ लेता है (मूल कंटेनर के किनारे पर आधारित है) ) और यह निर्धारित करने के लिए उन मूल्यों की तुलना करता है कि स्क्रीन पर psuedo तत्व कहां है।

यह तब तुलना करता है कि माउस कहाँ है। जब तक माउस नव निर्मित वैरिएबल रेंज में होता है तब तक यह सही रहता है।

ध्यान दें:

माता-पिता के तत्व को विश्वसनीय बनाना बुद्धिमानी है। यदि आपके पास एक पूर्ण स्थान पर स्थित प्यूटो तत्व है, तो यह फ़ंक्शन केवल तभी काम करेगा जब यह माता-पिता के आयामों पर आधारित हो (इसलिए माता-पिता को रिश्तेदार होना चाहिए ... शायद चिपचिपा या स्थिर काम करेगा .... मुझे नहीं पता)।

कोड:

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

  };      

}

सहयोग:

मुझे नहीं पता .... ऐसा लगता है जैसे कि गूंगा है और कभी-कभी एक गणना मूल्य के रूप में ऑटो वापस करना पसंद करता है। अगर सभी CSS में सेट हैं तो सभी ब्रम्हांड में काम करना है। इसलिए ... अपने प्यूसीडो तत्वों पर अपनी ऊंचाई और चौड़ाई निर्धारित करें और केवल उन्हें शीर्ष और बाएं से स्थानांतरित करें। मैं उन चीजों पर इसका उपयोग करने की सलाह देता हूं जो आप ठीक हैं इसके साथ काम नहीं करना। जैसे कोई एनीमेशन या कुछ और। क्रोम काम करता है ... हमेशा की तरह।


eventएक घटना हैंडलर फ़ंक्शन के माध्यम से पारित किया जाता है हर बार एक घटना को बंद कर दिया जाता है। जैसे क्लिक करना या टाइप करना। जब हम .click()फ़ंक्शन का उपयोग करते हैं, तो हम क्लिक इवेंट की प्रतीक्षा कर रहे हैं। हम .click(function(e){...})ईवेंट निर्दिष्ट करने और कहने के लिए कह सकते हैं eलेकिन यह केवल उपयोग करने के लिए स्वीकार्य है event

3
psEUdo, psUEdo नहीं!
biziclop

उपरोक्त कोड काम नहीं करता है, क्योंकि eventअपरिभाषित है।
सेबस्टियन जार्टनर

@SebastianZartner - इवेंट एक कीवर्ड है। यह तब होता है जब उपयोगकर्ता कुछ करता है। मैंने आपकी टिप्पणी के ऊपर इस दो टिप्पणियों की शाब्दिक व्याख्या की है। जब उपयोगकर्ता पृष्ठ के साथ इंटरैक्ट करता है, तो एक घटना को बंद कर दिया जाता है (ज्यादातर मामलों में)। इवेंट ईवेंट श्रोता ".click ()" से आने वाला कीवर्ड है। यदि कोई डेवलपर इवेंट के लिए किसी अन्य नाम का उपयोग करना चाहता है, तो वे इसे ".click (e)" जैसे इवेंट श्रोता में सेट कर सकते हैं, जो इसे देखने का एक अधिक सामान्य तरीका है। फिर भी .... भले ही मेरे ऊपर लिंक काम कर रहा हो, लेकिन मैं एक ऐसा भी शामिल करूँगा जो अधिक स्पष्ट है और कंसोल पर लॉग इन नहीं करता है, बल्कि जरूरतमंदों के लिए पेज पर जाता है।

मुझे यह उल्लेख करना चाहिए था कि यह फ़ायरफ़ॉक्स में काम नहीं करता है, क्योंकि 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

यह Fasoeu द्वारा नवीनतम CSS3 और JS 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

नहीं, लेकिन आप ऐसा कर सकते हैं

Html फ़ाइल में इस अनुभाग को जोड़ें

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

सीएसएस में आप इस तरह से कर सकते हैं

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

} आशा है इससे आपकी मदद होगी

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.