Asked  7 Months ago    Answers:  5   Viewed   242 times

My code is:

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

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

Please see this fiddle: http://jsfiddle.net/ZWw3Z/5/

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

p:before {
    content: '';
    position: absolute;
    left:100%;
    width: 10px;
    height: 100%;
    background-color: red;
}
    <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate...</p>

I would like to trigger a click event only on the pseudo-element (the red bit). That is, I don't want the click event to be triggered on the blue bit.

 Answers

28

This is not possible; pseudo-elements are not part of the DOM at all so you can't bind any events directly to them, you can only bind to their parent elements.

If you must have a click handler on the red region only, you have to make a child element, like a span, place it right after the opening <p> tag, apply styles to p span instead of p:before, and bind to it.

Tuesday, June 1, 2021
 
sohum
answered 7 Months ago
79

I've encounter the same problem while writing Selenium tests for Salesforce and managed to solve it by direct control over mouse using Actions.

Wrapper table for this button has hardcoded width of 250px, and you have spotted that. To locate where the mouse is, you can use contextClick() method instead of Click(). It simulates right mouse button so it will always open browser menu.

If you do:

Actions build = new Actions(Session.Driver);
build.MoveToElement(FindElement(By.Id("ext-gen33"))).ContextClick().Build().Perform();

you will spot that mouse moves to the middle of the WebElement, not the top left corner (I thought that it does too). Since that element width is constant, we can move mouse just by 250 / 2 - 1 to the right and it will work :) code:

Actions build = new Actions(Session.Driver);
build.MoveToElement(FindElement(By.Id("ext-gen33"))).MoveByOffset(124, 0).Click().Build().Perform();
Wednesday, August 11, 2021
 
Andrew Burton
answered 4 Months ago
22

The great comments here gave me the answer: It's possible to propagate the event to underlying elements manually by finding them using getIntersectionList() at the cursor positon.

$('svg').on('mousemove', function(evt)
{
    var root = $('svg')[0];
    var rpos = root.createSVGRect();
    rpos.x = evt.clientX;
    rpos.y = evt.clientY;
    rpos.width = rpos.height = 1;
    var list = root.getIntersectionList(rpos, null);

    for(var i = 0; i < list.length; i++)
    {
        if(list[i] != evt.target)
        {
            $(list[i]).mousemove();
        }
    }
});

Working example: http://jsfiddle.net/michaschwab/w0wufbtn/6/

If the other listeners need the original event object, check out http://jsfiddle.net/michaschwab/w0wufbtn/13/.

Thanks a lot!!

Wednesday, August 11, 2021
 
the_e
answered 4 Months ago
47

I have managed to fix this by doing something that feels unnatural and hacky:

function fadeIn (elem, fn) {
  var $elem = $(elem);

  $elem.addClass('is-animating');
  $elem.removeClass('is-hidden');

  // Smelly, setTimeout fix
  setTimeout(function () {
    $elem.removeClass('is-hiding');
  }, 0);

  $elem.on(transitionEndEvent, function () {

    $elem.removeClass('is-animating');

    if (typeof fn === 'function') {
      fn(); 
    }
  });
}; 

Adding the setTimeout function to the class that contains the transition-able property fixes the issue.

Working code here: Codepen fixed code

Saturday, August 14, 2021
 
maciekm
answered 4 Months ago
77
// Needed to read the "real" position
$.fn.adjustedPosition = function() {
    var p = $(this).position();
    return {
        left: p.left - this.data('dx'),
        top: p.top - this.data('dy')
    }
};

$(function() { 

    var img = $('img'),
        pos;

    // Calculate the delta
    img.each(function() {
        var po = $(this).position(), // original position
            pr = $(this).addClass('rot').position(); // rotated position

        $(this).data({
            dx: pr.left - po.left, // delta X
            dy: pr.top - po.top // delta Y
        });
    });

    // Read the position
    pos = img.adjustedPosition();    
    alert(pos.left + '/' + pos.top);     

    // Write the position
    img.css(pos);

    // Read the position again
    pos = img.adjustedPosition();    
    alert(pos.left + '/' + pos.top);

});

Live demo: http://jsfiddle.net/2gVL4/4/

So what is going on here:

  1. The CSS code that rotates the image is stored inside a special CSS class. I do this because I want to read the original position of the image (before rotating). Once I read that original position, I apply the .rot class, and then read the position again to calculate the difference (delta), which is stored inside the element's data().

  2. Now, I can read the position via the custom method adjustedPosition (which is defined above). This method will read the position of the element and then subtract the delta values stored inside the data() of the element.

  3. To write the position, just use the css(pos) method like normally.

Sunday, August 15, 2021
 
user1865027
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share