Implementing a hover info box - javascript

I have a calendar, and when the user hovers over a cell, a large-ish info box appears with details for that date. I am having some trouble though making the info box disappear when the user moves away.
I basically want it so that when the mouse cursor moves out of the calendar cell which is hidden by the info box it will disappear. But I'm having trouble with this because mouseenter and mouseleave get messed up by having the info box as the top element.
So I tried to get around this by using "placeholder" divs that are transparent, have the same shape and location as the calendar cell beneath it, and have a z-index of 1000 so they are above the info box. I then apply the mouseenter and mouseleave events to these divs instead.
There's two problems with this though. One, I have now messed up my HTML semantically. The divs have no purpose but to get around what seems to be a limitation. And secondly, they mess up my jQuery UI selection (I've applied it to the calendar cells - a click no longer selects a cell).
Is there a clean way to handle displaying an info box? There will be no user interaction with the info box -- it's just to display information.
EDIT: Here is some code:
<li>
<div class="day-content">
</div>
<div class="day-content-placeholder">
</div>
</li>
and CSS
li
{ position: absolute; width: 15%; height: 20%; top: ... left: ... }
.day-content
{ position: absolute; width: 100%; height: 100%; }
.day-content-placeholder
{ position: absolute; width: 100%; height: 100%; z-index: 1000; }
.popup
{ position: absolute; width: 300%; height: 300%; left: -150%; top: -150%; z-index: 500; }
and Javascript
var popup;
$('.week-content-placeholder')
.mouseenter(function()
{
popup = $('<div class="popup">'+a_lot_of_text+'</div>').insertAfter(this);
})
.mouseleave(function()
{
popup.remove();
});
That's not the exact code, but you get the idea. This works okay, but like I said, since .week-content-placeholder is above .week-content, the selection capability with jQuery UI doesn't work properly on .week-content.

You could modify your solution with the transparent "placeholder" divs in the following way:
Have the "placeholder" dive underneath the "calendar cell", using {zIndex: -1}.
When you enter a calendar cell, unhide the large "content" div and set {zIndex: 1000} on the "placeholder" div to bring it to the top.
Have a "mouseout" event on the placeholder div that will hide the "content" div and set {zIndex: -1} for the the "placeholder" cell.
Rather than create the "placeholder" cells in the HTML, you could create one in the javascript and move it to the postion of each "calendar" cell as you "mouseIn" it. You could also duplicate any "click" events on the "calendar cell" onto this one as well.
Let me know if this works.

The trick here is to make the info box a child of the cell:
<div id='box'>
Normal content
<div id='inner'>
This big box obscures everything in the cell!
</div>
</div>
The inner box is hidden until the hover occurs. Notice how with CSS we can make the box bigger than the cell itself with negative margins.
#box
{
width:100px;
height:100px;
margin:100px;
border:solid 2px darkblue;
position:relative;
}
#box #inner
{
display:none;
position:absolute;
background-color:#eeee00;
top:-10px;
left:-10px;
width:120px;
height:120px;
}
And you can use normal jquery hover because the hover covers box the box and it's child:
$('#box').hover(function(){
$('#inner').show();
},function(){
$('#inner').hide();
});
Here's it running:
http://jsfiddle.net/RbqCT/
You can create the info box dynamically as you do in your code.

Here's 15 different plugins that let you do this with jquery:
http://www.webdesignbooth.com/15-jquery-plugins-to-create-an-user-friendly-tooltip/

You could track mousemouse and use the offsetLeft + width and offsetTop + height of your hover trigger against the event.pageX and event.pageY to compare.

If you make this work as you described a tiny mouse movement that remains within the calendar cell (which is not even visible) leaves the popup in place, but a slightly larger movement that exits the cell makes the popup disappear.
The user sees only movement within the popup itself — small movement within the popup leaves it in place; large movement makes it go away.
I suggest triggering the disappearance of the popup on exiting the popup div itself. Any movement that remains within the "tip" panel leaves it up. I think that (1) this is better usability and (2) it avoids the whole problem with the obscured calendar cell event handling.
You could do that by adding a .mouseleave() handler to the div when you create it.

Related

Animating divs in a set

I currently have a list of objects (projects) that are presented to the user initially as div's that have have a 100px x 200px height/width, position absolute, and float left. This list is contained within an angular ng-repeat method (not sure that makes a difference in the overall question but figured I'd add it in just in case it does). There could be 100s of these divs on the particular project listing page. Currently, I have the page setup so that if you click one of the projects, it's details come up in a modal dialog box. This functionality is fine per the requirements for my project but I'd like to add some "umph" to it by adding in an animation that does the following:
1) If you click on one of the projects, the box expands up to fill the parent container that contains all the projects
2) As the div grows to fill the space or when it's full sized, I want to expose the details of the project itself. Essentially, when the project is unselected, it's just a title/description showing. When it is selected, the project div goes full screen, exposes all of it's details, and shows it's editable fields in the full screen version of the div.
3) When the user closes that full screen div, I'd like it to go back to it's original state in it's original position.
I'm only using the latest version of Chrome for this project so it doesn't need to be a cross browser solution. I'd prefer to keep the animation as close to pure css as possible and would prefer to leave jquery out of it.
I currently have no experience with css3 animations but got a book on it that I hope can teach me about this eventually. However, I figured I would ask in the mean time in case someone can help me out soon so I can put this functionality in while still meeting my deadline for the functionality.
Thanks in advance!
Create a second CSS class that can be added to your div element when it is selected, and removed when it is not. Something like
div {
top: 100px;
bottom: 200px;
left: 100px;
right: 300px;
transition: all 1s; /* animate changes */
}
.active {
top: 0px;
bottom:0px;
left: 0px;
right: 0px;
}
.content {
display: none; /* hide the content unless active */
}
.active .content {
display: block; /* show the content when .active class is added */
}
Make sure that the parent container fills the entire window and is itself set to positiion: absolute or position: relative. There will be a lot more details to work out as you go, but that should give you a framework to get started. You can then add or remove the .active class as needed with JavaScript.

Prevent centring on focused input in hidden overflow area

It is hard to explain with words so here's a fiddle I made to explain the problem better: http://jsfiddle.net/j2zurbbv/1/. When the first timeout fires the container div is not 'scrolled' which is the behaviour I want. However when the input is outside of the visible part of the div (as it is with the second timeout) the container div centres about this input.
Container css:
#container {
overflow: hidden;
height: 200px;
position: absolute;
width: 200px;
}
For the record I have only tested this on Chrome 37.0
Managed to work it out. Counter the scrolling that the browser does by doing document.getElementById('container').scrollTop = 0; whenever you programatically focus on an element outside of the visible area of an overflow: hidden div AND whenever a user inputs in such an element. Demonstrative JSFiddle (without prevention of input scrolling) http://jsfiddle.net/j2zurbbv/2/.

Flow and Scroll Text around non rectangular shapes

I have created a little code which lets text flow around some shapes. Using a simple Javsscript:
See http://jsfiddle.net/lobin/YPBmJ/2/
What I try to achieve is that the shape is fixed and when scrolling, the text will scroll around the shape. I let the shape stay fixed via a JS bound to the scroll event, but it seams the rendering does not adopt itself to the new situation (See jsfiddle).
Any Ideas how that could work?
HTML:
<div class="box"><div class="shapewrapper"></div>Some long Text</div>
CSS:
.box {
width:600px;
height:400px;
position: absolute;
overflow-y: scroll;
}
.box .shapewrapper {
position: relative;
}
.box .shapewrapper .left {
background-color: #f00;
height:1px;
float:left;
clear:left;
}
JS:
var hbratio=10;
var h=$(".box").height();
for (i=h;i>0;i--) {
b=Math.round(i/10);
$(".shapewrapper").prepend('<div class="left" style="width:'+b+'px;" />');
}
$(".box").scroll(function() {
var y=$(".box").scrollTop();
$(".shapewrapper").css("top",eval(y)+'px');
});
(Idea from http://www.csstextwrap.com)
I don't know if there is a way to achieve this with css (alone), but I came up with a solution that involves jQuery.
Whenever the user scrolls the ".box" element, the top margin of the first ".left" element should be adjusted.
$(".box").scroll(function() {
$(".box .left").first().css("margin-top", $(this).scrollTop()+"px");
});
In order to make this work, the user must actually scroll the box element, so I changed the CSS of the box to overflow:auto. It would also work of the user scrolls the parent-element, but then the selector for the scroll event would need to be changed to the parent element.
I created a new jsFiddle to demonstrate it: http://jsfiddle.net/EwQ5J/1/

Centering text over an IMAGE BUTTON, while driving the text hover effect from hovering over the image- not the text

I have a set of buttons in which I need the text to - eventually - change based on country.
This means that I have to use a text element to be part of the button. Since the button has hover effect, I need the text to be contained inside the image div.
By using the "", I get the text to be position correctly, but the problems are:
A: the text responds to the pointer way outside the image boundary (which actually causing the click to activate a different button.
B: if the pointer is placed directly over the text, only the text get highlighted (through the hover effect), but not the button.
I am looking for a solution (either via CSS or JavaScript) that will make the button perform correctly e.g. the button will respond pointer hover over to the image only, but will still highlight the text (as if the text was part of the - and not separate as it actually is).
Note that since the text and image elements are screen-size adaptive, all distances and sizes must be percentage based)
See Fiddle HERE:
Note what happens when you hover just on top of the image. Also note what happens when you touch the edges of the image VS the center...
<div id="main_positioning_container">
<div id="my_account_dashboard_container">
<div id="contact_information_icon"
style="color:#292726"
onMouseOver="this.style.color = '#f48325'"
onMouseOut="this,style.color = '#292726'" >
<img src="../icons/icon_ContactInforrmation_inactive.png"
img onMouseOver="this.src='../icons/icon_ContactInforrmation_hover.png'"
onMouseOut="this.src='../icons/icon_ContactInforrmation_inactive.png'"
alt="icon_ContactInforrmation_inactive"
width="100%"
hight="auto"
style="margin-bottom: -20%;">
<p align="center">Contact Information</p>
</div>
</div>
</div>
#main_positioning_container {
position:relative;
width: 100%;
top: 75px;
left: 0px;
}
#my_account_dashboard_container {
visibility:visible;
}
#contact_information_icon {
position: absolute;
width: 25%;
z-index: 3;
color: #292726;
font: Kalinga;
font-size: 100%;
margin-top: 13.75%;
margin-left: 7.5%;
height: 20px;
}

Interactive HTML webpage

EDIT: Thanks for a lot of great examples on how to solve these. I cant decide between who to accept yet, but I will go though all examples and see which I like the most. Great feedback guys! =D
I normally do these kind of things in flash, but this time it has to be compatible with mac, iPads and all those units too.
So, what do I need help with?
I've got a picture, with some "hotspots" on. I want to be able to click any of those hotspots to show some information.
This should be fairly basic and easy to achieve, but since I've never done this in html before I have to ask you guys =)
So, what would be the best way to do this? It have to be compatible with any browser and device, and it doesnt need to be very advanced. If it's possible to add effects to the box (sliding out, fading in, or anything like that) then thats a nice bonus, but not something I need.
Any help would be great!
BREAKDOWN:
I have a background image with some "hotspots" (numbers 1 and 2 in my example). The users should be able to either hover the mouse over any of these or click it to get more information, as seen in picture #2
This is that happens when you hover/click any of these hotspots.
Text and image is displayed inside a nice little info box.
If the user clicks "more information" it will open up even further to display more information if available. Like in this img:
I don't think the Javascript approach is really necessary here. I created a little CSS-only mock-up for you on JSBin.
Basically the point is that you enclose the image in a relatively positioned div, then absolute position the hotspots inside the same div. Inside the hotspots divs you will have the more info elements, showing only on :hover of their parents.
This makes it simple, and far more accessible.
Update: cropping the image equally from both sides
If you want to keep the image centered and still not use any javascript, you could set the required image as a background-image of the container, and setting its background-position parameters to center center.
You would have to make sure that the width of this div is set to the width of your image, and the max-width to 100%, so that when the window gets resized below the image width it stays at the center.
Now, a problem that I encountered here is how to make the hotspots stay center relatively to the image. I solved it this way:
I created a wrapper div for the hotspots with these characteristics:
margin: 0 auto;
position: relative;
width: 0px;
This basically makes sure that the wrapper div finds the center of our image. Then, you would position the hotspots relatively to the top-center position of the image, instead of the top-left as a starting point.
Then you have what you are looking for.
Working demo
Here's another approach, and in my opinion far superior to using a map or excessive JS. Place <div> elements on top of the element with the background-image and have HTML and CSS do the heavy lifting for you.
See it on JSFiddle
HTML
The HTML should seem pretty each enough to understand, we create <div>s with the class hotspot and rely on certain things being present. Namely .text (to show digit), .hover-popup (to show on hover) and .click-popup (which is inside .hover-popup and is shown when clicked).
<div id="hotspot1" class="hotspot">
<div class="text">1</div>
<div class="hover-popup">
I was hovered!
<div class="click-popup">
I was clicked on!
</div>
</div>
</div>
<div id="hotspot2" class="hotspot">
<div class="text">2</div>
<div class="hover-popup">
I was hovered!
<div class="click-popup">
I was clicked on!
</div>
</div>
</div>
CSS
This is where most of the magic happens, see the comments for further explanation.
/* These two position each hotspot */
#hotspot1 {
left:15%; /* we could use px or position right or bottom also */
top:20%;
}
#hotspot2 {
left:35%;
top:25%;
}
/* General styles on the hotspot */
.hotspot {
border-radius:50%;
width:40px;
height:40px;
line-height:40px;
text-align:center;
background-color:#CCC;
position:absolute;
}
.hotspot .text {
width:40px;
height:40px;
}
/* Show the pointer on hover to signify a click event */
.hotspot .text:hover {
cursor:pointer;
}
/* hide them by default and bring them to the front */
.hover-popup,
.click-popup {
display:none;
z-index:1;
}
/* show when clicked */
.hotspot.clicked .click-popup {
display:block;
}
/* show and position when clicked */
.hotspot:hover .hover-popup {
display:block;
position:absolute;
left:100%;
top:0;
width:300px;
background-color:#BBB;
border:1px solid #000;
}
JavaScript (with jQuery)
Unfortunately you're going to have to use some JavaScript for the clicking part as CSS doesn't have a 'clicked' state (outside of hacks with checkboxes). I'm using jQuery because it's dead easy to do what I want.
$(document).ready(function () {
$('.hotspot').click(function () {
$(this).toggleClass('clicked');
});
});
Creating the arrow
Over at css-tricks you can find a tutorial for attaching an arrow to a element using the :before and/or :after pseudo-elements. You can even 'simulate' a border around them by placing the :after element on top of the :before. But yea, lots of resources on how to do this.
You should be able to use the onclick or OnMouseOver event in the map area (define the href as "").
An example using OnMouseOver is here: http://www.omegagrafix.com/mouseover/mousimap.html
Give a class for that image in html (Ex: imgclass). And in javascript(using jquery), build that hover box in html format and bind it to 'mouseover' event of that image.
For example:
function bindhtmltoimage() {
myimg = $('body').find('.imgclass');
divSlot.each(function (index) {
$(this).bind('mouseover', function () {
try {
//position the hover box on image. you can customize the y and x axis to place it left or right.
var x = $(this).offset().left;
var y = $(this).offset().top;
var position = $(window).height() - ($("#divHover").height() + y);
var widthposition = $(window).width() - ($("#divHover").width() + x);
if (position < 0 || widthposition < 0) {
if (position < 0) {
$("#divHover").css({
position: 'absolute',
left: x + 20,
top: y - $("#divHover").height() - 20
});
}
if (widthposition < 0) {
$("#divHover").css({
position: 'absolute',
left: x - $("#divHover").width(),
top: y + 20
});
}
}
//build your html string for that hover box and apply to it.
$('#divHover').html("your Html content for that box goes here");
$('#divHover').show();
//if you want the box dynamically generated. create the html content and append to the dom.
}
catch (e) {
alert(e)
}
});
});
}
it will work fine in desktop and mobile. if you face any problem in touch devices, bind the function to click event instead of 'mouseover'.
Also, for map approach, i strongly recommend SVG instead of images.

Categories

Resources