Blakeyrat's JavaScript Is Rusty Thread



  • @wharrgarbl ?

    That's totally unnecessary. If you do that mouse: passthrough or whatever CSS style, that works by default. (Shockingly, something in the web development cornucopia of crap works right without having some weird quirk.) So getting clicks behind the cosmetic DIV is easy.

    What I'm struggling with is how to ensure my client handlers will run first on every site, which I'm beginning to think is literally impossible.



  • @blakeyrat It's unecessary for their original question, but it seem to be able to do what you want. It doesn't use passthrough, and locates the control that would receive the click using mouse coordinates. It looks too hacky for me to like it, but maybe it works well enough.



  • @wharrgarbl But I don't need to do that. That bit of the problem is solved.



  • @blakeyrat said in Blakeyrat's JavaScript Is Rusty Thread:

    (The tough one) Create a simulcrum of the page's visible divs atop my div to identify certain parts of the page.

    I guess this is the currently unsolved part then?

    I remember that a chrome extension that shows a border over a page your elements as you hover over them. It was one to hide annoying elements (not an ad-blocker, it was an image blocker, or flash blocker).

    So it's definitely possible, but the chrome web store is blocked here at work, so I can't find it.



  • @wharrgarbl said in Blakeyrat's JavaScript Is Rusty Thread:

    I guess this is the currently unsolved part then?

    Well, I've kind of moved off that idea, since a bunch of other people in this thread said it'd be a better idea to try and intercept click handlers before the site can react to them. Which is better for a few reasons: for one thing, if the page is resized, I don't have to like "redraw" my areas manually.

    The catch is getting the click capture right.



  • @blakeyrat isn't that possible to solve with that function I found on stackoverflow?

    It should allow you to:

    1. put a div a non-passtrough div in front of everything (like a pay wall)
    2. your div is the only one to get a click event from the browser
    3. identify the mouse coordinates
    4. identify the element below your div
    5. do your stuff that needs to happen first
    6. call the the underlying element's event


  • @wharrgarbl Oh now I see where you're going with this.

    So the click is intercepted by my covering DIV (which doesn't turn off mouse events) but then I can detect the actual element underneath it. Ok, sorry, I wasn't following you before.

    That's an interesting possibility but I need it to work for Mousemoves too, so I can highlight the element before the user clicks. Might be worth some experimentation.



  • @blakeyrat The problem there is that the possibility that you pointed out before still exists: if the site registered a capturing event handler on one of the elements above your div, and stopped event propagation there, your div still wouldn't see the clicks.

    I'm still not sure of any not-horrible way that would guarantee that the site can't register an event handler that prevents yours from seeing the events. There might not be one.

    It does look like you can register the capturing click event handler on document instead of document.body... that would be a little better, but it doesn't really solve the problem.

    If your code is running in Chrome's privileged extension environment, there might be a way to capture the event first, at the window chrome level -- before it even gets to the page -- but I wouldn't know how.



  • @anotherusername Right; it seems the makers of DOM didn't ever anticipate the order event handlers fire in as being important. Which, to be fair, they also never anticipated code being installed on a website that wasn't under the control of the maker of that website.



  • @anotherusername said in Blakeyrat's JavaScript Is Rusty Thread:

    if the site registered a capturing event handler on one of the elements above your div, and stopped event propagation there, your div still wouldn't see the clicks.

    Maybe this is rare enough you could afford to not support it. I took look at the chrome extensions documentation and didn't find anything.



  • What would cause getBoundingClientRect() to return 0, 0, 0, 0 for an element I'm seeing right there on the damned page with my human eyeballs?

    I thought maybe because it's position: absolute, but docs say that should work fine.

    Stumped.



  • @blakeyrat That's pretty strange. Does getClientRects() return anything?

    This might be a clue:

    The returned rectangles do not include the bounds of any child elements that might happen to overflow.

    Is the element you're seeing actually a :before or :after pseudo-element? getBoundingClientRect() might be giving you the size of the element that it belongs to.



  • @anotherusername said in Blakeyrat's JavaScript Is Rusty Thread:

    Is the element you're seeing actually a :before or :after pseudo-element?

    How would I tell in Chrome's DOM tree?

    I don't think it is, but are those like... highlighted somehow or...?

    @anotherusername said in Blakeyrat's JavaScript Is Rusty Thread:

    getBoundingClientRect() might be giving you the size of the element that it belongs to.

    But wouldn't the element it belongs to have dimensions other than 0, 0, 0, 0?



  • @blakeyrat said in Blakeyrat's JavaScript Is Rusty Thread:

    How would I tell in Chrome's DOM tree?

    0_1502487286372_8c182df7-e77a-421a-a15c-5c73b23e103e-image.png

    If you expand the element, you should see them at the beginning or end of the element's content tree. The ::before or ::after can be selected in the tree, like a real element, and it'll show its styles. It'll also show ::before and ::after styles if you select the element itself.

    @blakeyrat said in Blakeyrat's JavaScript Is Rusty Thread:

    But wouldn't the element it belongs to have dimensions other than 0, 0, 0, 0?

    It wouldn't necessarily have to... if the :before or :after is positioned absolute, the size/location of its parent element doesn't matter.



  • @anotherusername It's not a before or after, it's there on the page.

    I'm trying to copy and paste its computed style but apparently the geniuses who make the Chrome developers tools haven't figured out this complex "copy" thing yet.



  • Here we go:

    border-top-color: rgb(x, x, x);
    border-top-style: solid;
    border-top-width: 1px;
    bottom: 0px;
    cursor: default;
    display: block;
    font-family: Arial, sans-serif;
    height: 40px;
    position: absolute;
    user-select: none;
    width: 189px;
    -webkit-font-smoothing: antialiased;
    -webkit-tap-highlight-color:rgba(0, 0, 0, 0);
    

    It has a height, width, display: block, position: absolute. Not sure why any of that would create dimensions of 0, 0, 0, 0.



  • @blakeyrat well, there's nothing unusual there...

    0_1502490148596_bde06900-6bcc-4f3d-9015-5dd1900a6850-image.png

    Must be something else going on, but I don't know what. ¯\(°_o)/¯



  • @anotherusername Like I said, I'm totally stumped.



  • @blakeyrat ...nobody's done anything truly awful, like changing the definition of getBoundingClientRect(), right?



  • @anotherusername It works on about 50 other DIVs on the same web page.



  • @blakeyrat this might be a stupid question, but have you tried executing getBoundingClientRect() from the dev console? Does it return all 0s there too?



  • @anotherusername WORK IS OVER.

    Good idea though I'll try it monday if I remember.



  • @blakeyrat ...because if you happen to have code somewhere like this:

    elem.style.display = "none";
    
    /* code... code... code... */
    
    console.log(elem.getBoundingClientRect());
    
    /* code... code... code... */
    
    elem.style.display = "";
    

    ...it's going to give you a DOMRect { x: 0, y: 0, width: 0, height: 0, top: 0, right: 0, bottom: 0, left: 0 } instead of what you'd expect... if the code doesn't halt while the element's hidden to allow redraw to occur, you wouldn't even see it flicker. But calling getBoundingClientRect() all by itself from the dev console should work...


  • Winner of the 2016 Presidential Election

    @blakeyrat said in Blakeyrat's JavaScript Is Rusty Thread:

    @anotherusername said in Blakeyrat's JavaScript Is Rusty Thread:

    You say that you don't have control over their DOM/JS. I take it you're able to add a div to the root node, at least, and add your own JS (which could interact with their DOM/JS).

    I can do everything a Chrome extension can do, which is quite a bit.

    @anotherusername said in Blakeyrat's JavaScript Is Rusty Thread:

    So the event handler, after capturing the event at the root node level, stops the event's propagation (none of the event handlers on descendant elements will even be notified of this event), and also prevents the default (the browser's default action, if any -- e.g. for hyperlinks -- won't be taken).

    But does it allow me to cover the page with a graphic effect DIV, or would the DIV covering the page receive all the clicks making it useless to find what the actual page element clicked was?

    The Adblock Plus chrome extension does the things you're describing somehow. This image shows the "block element" mode in action, with the mouse hovering over your profile image:
    0_1502512047720_4c213267-82c3-4b67-88d9-50c1fa61ba02-image.png

    (I guess something in there messes with @ben_lubar's category recognition, since it thinks this is from a mafia category.)

    And after clicking, I get this pop-up:
    0_1502512246099_a57f47d7-4bff-46ab-98b4-81c093e6e6cc-image.png

    The source code is available here:



  • @dreikin said in Blakeyrat's JavaScript Is Rusty Thread:

    (I guess something in there messes with @ben_lubar's category recognition, since it thinks this is from a mafia category.)

    Yes... my sig does.


Log in to reply
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.