Forums

The forums ran from 2008-2020 and are now closed and viewable here as an archive.

Home Forums JavaScript Get a dynamically created div's top/bottom edge consistently to set as intended.

  • This topic is empty.
Viewing 7 posts - 1 through 7 (of 7 total)
  • Author
    Posts
  • #241934
    alxfyv
    Participant

    I have a dynamically created <div>, call it “popup,” that pops up on a click event. If the event is in the right half of the view port, popup should have its right edge at the event.clientX position. If in the left half, its left edge should be at .clientX. This works correctly all the time. If the event is in the bottom half of the view port, popup’s bottom edge should be at the .clientY position. If in the top half, its top edge should be at .clientY. This works sporadically.

    There is a Pen, Table Play , at CodePen. Click on a class title or an instructor’s name to activate popup. Sometimes the top/bottom edge is correctly aligned at .clientY, sometimes .clientY is in between the top and bottom edges.

    The JS function for calculating popup’s position begins on JS line #233; its scheme is simple. vpW = the view port width. vpH = view port height.

    vW = cursorX;          //cursorX === event.clientX
    if ( vW > vpW/2 ) { vW -= popup.offsetWidth; }
    vH = cursorY;         //cursorY === event.clientY
    if ( vH > vpH/2 ) {vH -= popup.offsetHeight; }
    popup.style.left = vW + 'px';
    popup.style.top = vH + 'px';
    

    In Table Play, click on a class title or instructor’s name then scroll the page and click on the same again. The .clientY position will sometimes appear at the top/bottom edge as intended; sometimes it will appear somewhere in between top and bottom edges rather than at the top or bottom edge.

    If desired, you can see the problem on the /test-table page of my site.

    Any help in getting this problem solved will be much appreciated. Thank you for your interest in my question and for your time.

    -Steve

    #242025
    ershwetabansal
    Participant

    You should add scrollTop and scrollLeft to the popup top and left repectively.

    Top and left of an absolute positioned element is relative to the document and not the viewport.

    #242035
    alxfyv
    Participant

    @ershwetabansal

    Thanks for your interest and suggestion, but I'm such a novice that at first I was uncertain what it is you want me to do.

    But after thinking about it, I understood that I had to account for the distance the page top had scrolled up from the view port top. That distance is gotten by document.body.scrollTop. That's what I have to add to event.clientY (the distance from the click point up to the view port top) to get popup's total distance to be used for its CSS top property.

    For those who might like to see it, I'll give the code for the function here.

    // positon popup on page relative to cursor
    // position at time of click event
    function positionPopupOnPage( evt ) {
    
    var VPWH = [];              // view port width / height
    var intVPW, intVPH;         // view port width / height
    var intCoordX = evt.clientX;        // click point (x,y) coordinates
    var intCoordY = evt.clientY;
    var intDistanceScrolledUp = document.body.scrollTop;
               // distance the page has been scrolled up from view port top
    var intPopupOffsetTop = intDistanceScrolledUp + intCoordY;
            // add the two for total distance from click point y to top of page
    
    var intDistanceScrolledLeft = document.body.scrollLeft;
    var intPopupOffsetLeft = intDistanceScrolledLeft + intCoordX;
    
    VPWH = getViewPortWidthHeight();
    intVPW = VPWH[0];
    intVPH = VPWH[1];
    popup.style.position = 'absolute';
        // if not display: block, .offsetWidth & .offsetHeight ===  0
    popup.style.display = 'block';
    popup.style.zIndex = '10100';
    
    if ( intCoordX > intVPW/2 ) { intPopupOffsetLeft -= popup.offsetWidth; }
        // if x is in the right half of the viewport, pull popup left by its width
    if ( intCoordY > intVPH/2 ) { intPopupOffsetTop -= popup.offsetHeight; }
        // if y is in the bottom half of view port, pull popup up by its height
    popup.style.top = intPopupOffsetTop + 'px';
    popup.style.left = intPopupOffsetLeft + 'px';
    
    }  // end fn positionPopupOnPage
    

    The function getViewPortWidthHeight() is the last function defined in the pen Popup Project for those who want it.

    Thanks for your help. You got me thinking in the right direction and helped me figure it out for myself. That was great.

    #242046
    Mottie
    Member

    It looks like the method used to get the scrollTop will always return zero; try this code instead:

    var intDistanceScrolledUp = window.pageYOffset || document.documentElement.scrollTop;
    
    #242053
    alxfyv
    Participant

    @mottie

    Thanks for your interest and your note. They are much appreciated.

    the method used to get scrollTop will always return zero

    From reading the MDN documentation for Window.scrollY and Window.scrollX, in particular the examples for compatibility with IE<9, it seems that document.body.scrollTop is the fallback in those cases where other methods, i.e. window.pageYOffset and document.documentElement.scrollTop, may not work.

    From this I infer that document.body.scrollTop will always work, or at least has the best chance of working. I know that in my case it returns zero only when the page has not been scrolled. When the document has been scrolled it returns the correct positive value because popup always is properly locating at the event.clientY position.

    Am I understanding this incorrectly? May I ask what it is that makes you think document.body.scrollTop will return a false negative, i.e. a false zero value?

    In any case, I'm going to use your example, with document.body.scrollTop as the third fallback, because that conforms to the MDN examples and because it is the more elegant.

    Again, thanks for your interest and suggestion, and please let me know your thinking on why document.body.scrollTop will return a false negative. I'm a complete novice at all this and anxious to understand.

    BTW: love your avatar.

    #242083
    Mottie
    Member

    Well, when I was looking at your popup project demo, I added a console log to show the document.body.scrollTop value, and it was always returning zero, even when the window was at the bottom of the page.

    You shouldn’t have to worry about IE < 9 anymore, the document.documentElement.scrollTop is there as a fall back in case the window.pageYOffset isn’t defined or zero.

    I did replace the document.body.scrollTop with the code I shared and it was working as I expected, at least in Chrome.

    #242085
    alxfyv
    Participant

    I understand. Thank you.

    In the meantime, a user at Sitepoint pointed out that if I make popup position: fixed I can simply use the event.clientX/Y coordinates as the offsets. Ah well, it’s all a process.

Viewing 7 posts - 1 through 7 (of 7 total)
  • The forum ‘JavaScript’ is closed to new topics and replies.