Mufeed Ahmad
Mufeed Ahmad

Reputation: 485

Unable to calculate the hover element's exact position

I am just trying to get the mouse hover div's position at the right according to the space around. Somehow I am able to do this in first two columns but not for other columns. May be my calculations while writing the condition state are wrong.

Can anyone please help?

JS Fiddle URL:

http://jsfiddle.net/mufeedahmad/2u1zr11f/7/

JS Code:

 $('.thumb-over-team li').find('.cover').css({opacity:0});

        $('.thumb-over-team li').on('mouseenter', function(){    

                var $this = $(this), 
                    thisoffset = $this.position().left,
                    openDivId = $(this).find('.cover'),
                    thumbContainer = '.thumb-over-team',
                    speedanim = 200;


                 if(thisoffset + openDivId.outerWidth() >= $(thumbContainer).outerWidth()){
                     //thisoffset = $(thumbContainer).outerWidth() - openDivId.outerWidth() - 212;
                    thisoffset = thisoffset - openDivId.outerWidth()+10;                     
                     openDivId.stop().css({'z-index':'9999'}).animate({'opacity':'1', 'left':-thisoffset}, 200);
                     }else{                      
                         openDivId.stop().css({'z-index':'9999'}).animate({'opacity':'1', 'left':'212px'}, 200); 
                     }






        }).on('mouseleave', function(){         
            $(this).find('.cover').stop().css({'z-index':'-1'}).animate({'opacity':'0', 'left':'200px'}, 200);

        });

        $('.close-parent').on('click', function(){          
            $(this).parents('.cover').stop().css({'z-index':'-1'}).animate({'opacity':'0', 'left':'200px'}, 200);

        });;

Upvotes: 0

Views: 176

Answers (2)

E. Serrano
E. Serrano

Reputation: 5024

Fresh take on the problem, essentially based on the main issue: the expandable text block (.cover) used to add its width to the container (.thumb-over-team). This altered the calculations on available container space, and made the text containers go off screen.

The solution is to make sure the expandable .cover elements aren't contained inside the .thumb-over-team element, so they won't impact the calculations on available width.

Here is a JSFiddle containing this new approach: link.

Explanation of how it works:

The idea was to create a separate element called .cover-container and let's put all the expandable .cover elements in there.

We want to associate every image in the li elements in .thumb-over-team with their appropriate .cover (so the first image triggers the first .cover to show, the second image would show the second cover, and so on.) We achieve is by finding out the index of the element that triggered the event:

thisLiIndex = $this.index() + 1

And then selecting the cover in the matching position:

openDivId = $('.cover-container .cover:nth-child(' + thisLiIndex + ')')

The expandable covers shouldn't interfere with the mouseenter or mouseleave events of .thumb-over-team, so we make it to ignore mouse events via CSS:

.cover-container{pointer-events:none;}

Changing from one image to another would automatically trigger new events, so the expanding covers stay visible when the mouse stays on the images, but close automatically when the mouse exits them.

Since the covers are now outside of $(thumbContainer), openDivID.outerWidth() does not alter $(thumbContainer).outerWidth(), and we can use that safely in our positioning.

If I understand the placement that you want, for covers that fit, the position is the current offset (position of the li element that triggered the event) plus the width of the image and some subtle margin

imageWidth + rightSeparation + thisoffset

And for covers that won't fit inside of the screen, we keep them just inside of the screen

thisoffset = $(thumbContainer).outerWidth() - openDivId.outerWidth();

Upvotes: 0

E. Serrano
E. Serrano

Reputation: 5024

In your first conditional, try to calculate the position of the offset as:

thisoffset = ($(thumbContainer).outerWidth() - openDivId.outerWidth() - thisoffset);

That way, you're adjusting the appearing square (.cover) when it doesn't fit inside the container, to be as close possible to its rightmost edge: (maximum width - appearing square width - current li position)

Calculated this way, you can animate it with the new offset in positive:

openDivId.stop().css({'z-index':'9999'}).animate({'opacity':'1', 'left':thisoffset}, 200);

See it working here.

For elements that "almost" fit, the current system isn't completely precise because of what I already pointed out in my previous comment: the appearing square, even if it were at 0 opacity, would still be inside the containing element (($(thumbContainer)) or .thumb-over-team) and it would add its width to the total width of the container.

So your conditional may think that there's enough available space in the container to make the expandable element fit, but that would go out of the screen. As an example, notice that there's a horizontal scrollbar from the very beginning, caused by this effect, where your containing .thumb-over-team element doesn't fit in the screen.

But I would say that more precision in this point would require a fresh new approach to your system where the appearing .cover elements were out of the containing ul .thumb-over-team

Upvotes: 1

Related Questions