How to create a floating div with jQuery - javascript

When the mouse is over an element A of a certain class , another floating div B, which contains a link, should appear. B should disappear as soon as the mouse has left A and B.
How can I do this with jQuery?
jsFiddle
var container = $('#container');
var area = $('.area'); // this is A
var position = area.offset();
var floating = $("<div />", {
css : { "position" : "absolute",
"top" : position.top - 30,
"left" : position.left + 20,
"border" : "1px solid #000",
"padding" : "5px",
"display" : "none",
"z-index" : "100",
"background-color" : "#F00"
}
})
.text('Hello World'); // this is B
container.css('position', 'relative');
container.append(floating);
function show() {
floating.show();
}
function hide() {
floating.hide();
}
area.on('mouseenter', show);
area.on('mouseleave', hide);
floating.on('mouseenter', function(event) {
console.log("floating: mouseenter");
area.off('mouseenter', show);
area.off('mouseleave', hide);
});
floating.on('mouseleave', function(event) {
console.log("floating: mouseleave");
area.on('mouseenter', show);
area.on('mouseleave', hide);
});
My problem is that evertime the mouse enters B, B disappears already. I need to do this with jQuery, not only CSS.

I'm not sure why you have to put the floating div in the jQuery. This is probably how I would achieve something similar to what you want.
http://jsfiddle.net/A2gFb/6/
Just put the hidden float in the HTML,
<div class="area">luptatum zzril
<div class="fixed">Hello World!</div>
</div>
with proper CSS set.
.area {
position: relative;
color: #0F0;
font-weight: bold;
/* you may want to set the width/height here as well*/
}
.fixed {
position: absolute;
top: 20px;
left: 20px;
border: 1px solid black;
padding: 5px;
z-index: 100; /* Thanks Diego for pointing out the typo here */
background-color: red;
display: none;
}
And the jQuery would be as simple as this:
$(".area").mouseenter( function() {
$(".fixed").show();
});
$(".area").mouseleave( function() {
$(".fixed").hide();
});

The major problem you are having is that the mouseleave event for your green text is firing before the mouseenter for your floating div. To fix this I made a variable to track the mouse being in the float and used a setTimeout in the hide() function to check for this variable after 100 ms. You could probably go lower if you were worried about the delay. Here's the fiddle.
At the top of the javascript:
var inFloat = false;
The hide() function becomes:
function hide() {
setTimeout(function(){
if (!inFloat)
floating.hide();
},100);
}
And your floating mouse events become:
floating.on('mouseenter', function(event) {
inFloat = true;
});
floating.on('mouseleave', function(event) {
inFloat = false;
floating.hide();
});
You still have the issue that the floating div has a fixed position that isn't related to the mouse position, so it may be awkward to hover over the link and then move to floating div at times.

just add:
floating.on('mouseenter', show);
floating.on('mouseleave', hide);
it works on jsFiddle.
By the way, I suggest you to not use "show" and "hide" as function name since they already exist in jQuery. showTooltip and hideTooltip can be good names.

Related

jQuery animate scrollTop goes up then back down

I have a function that checks if there are any errors on the page and auto scrolls to them. The problem that I'm having is it scrolls up to them but then comes back down to where it was before. I'd like it to scroll up and stay there.
$(".submit_button").click(function (event) {
event.preventDefault();
var errorElements = $(".error").filter(":visible");
if (errorElements.size() > 0) {
target_top = $(errorElements).offset().top;
$('html, body').animate({
scrollTop: target_top
}, 800);
}
return false;
});
The problem is in your selector. I know why it's done. Any web dev that's been in this long enough has been using that for as much cross browser compat as possible, and yet still encountered this issue. The problem is, you're calling animate:scroll on 2 items consecutively using this selector.
The better way, in short, would be to check if it is a WebKit browser or not. Reason being is that non-WebKit tend to use html whereas WebKit browsers tend to use body (and sometime html). This can cause such confusion as you face now.
The simple short term solution is to use something like /WebKit/i.test(navigator.userAgent) in your click callback. This will help you assign only one selector to the animate call.
Example
var selector = /WebKit/i.test(navigator.userAgent) ? 'body' : 'html';
$(selector).animate( // ...
Test Snippet
$(function() {
// simply to make filler divs for scrolling
for (var i=0;i<10;i++) $('<div />', { 'id': 'div'+i, 'style': 'background-color: '+String.randColorHex()+';' }).append($('.temp').clone().removeClass('temp')).height($(window).height()).appendTo($('body'));
/*------------------------------------------*/
/***S*O*L*U*T*I*O*N***/
var divID = 0;
function btnCheck() { // IGNORE, simply to turn buttons on and off when reaching end
$('#btnScrollDown').prop('disabled', divID>=9);
$('#btnScrollUp').prop('disabled', divID<=0);
}
$(document)
.on('click', '#btnScrollDown', function() {
if (divID < 10) {
divID++;
// broke everything down so it's easy to see. You can shorten this in a few ways.
/*THIS HERE-> */var selector = /WebKit/i.test(navigator.userAgent) ? 'body' : 'html',
scrollSelector = '#div' + (divID),
scrollTop = $(scrollSelector).offset().top
props = { scrollTop: scrollTop },
time = 800;
$(selector).animate(props, time);
// simply to turn buttons on and off when reaching end
btnCheck();
}
})
.on('click', '#btnScrollUp', function() {
if (divID > 0) {
divID--
// broke everything down so it's easy to see. You can shorten this in a few ways.
/*THIS HERE-> */var selector = /WebKit/i.test(navigator.userAgent) ? 'body' : 'html',
scrollSelector = '#div' + (divID),
scrollTop = $(scrollSelector).offset().top
props = { scrollTop: scrollTop },
time = 800;
$(selector).animate(props, time);
// simply to turn buttons on and off when reaching end
btnCheck();
}
});
});
html, body, div { margin: 0; padding: 0; width: 100%; }
.buttons { display: inline-block; left: 1em; position: fixed; text-align: center; top: 1em; }
button { margin: .25em; padding: .1em .3em; width: 100%; }
.temp { dislpay: none; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/JDMcKinstry/String.randColorHex/0c9bb2ff/String.randColorHex.js"></script>
<section class="buttons">
<button id="btnScrollUp" disabled>Scroll To Next Div Up</button><br />
<button id="btnScrollDown">Scroll To Next Down</button>
<sub><i>this isn't fully managed, only use buttons to scroll!</i></sub>
</section>
<table class="temp"><tr><td></td></tr></table>

Javascript button appear animation

I have the back to top button that appears when you reach a point on the page, which is working fine, however, when it appears the text is on two lines until the box has finished the animation to appear. So, is there anyway to prevent this? What I mean by the animation is: btt.show('slow');
Code:
$(document).ready(function () {
var btt = $('.back-to-top');
btt.on('click' , function(e) {
$('html, body').animate({
scrollTop: 0
}, 500);
btt.hide('slow');
e.preventDefault();
});
$(window).on('scroll', function () {
var self = $(this),
height = self.height(),
top = self.scrollTop();
if (top > 500) {
btt.show('slow');
} else {
btt.hide('slow');
}
});
});
Example: http://codepen.io/Riggster/pen/WvNvQm
The problem is caused by animating the width of a box, I think it might be better to animate the position of it instead, but - even better - lets use CSS animations!
$(window).on('scroll', function () {
if ($(window).scrollTop() >= 500) {
$(".button").addClass('show');
} else {
$(".button").removeClass('show');
}
});
#wrapper {
width: 100%;
height: 2000px;
}
.button {
position: fixed;
bottom: 50px;
right: -100px;
/* You might still need prefixes here. Use as preferred. */
transition: right 500ms;
}
.button.show {
right: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<div id="wrapper">
<div class="button">Here's my button!</div>
</div>
I've defined your button as hidden by default, by giving it a position of right: -100px. When we hit the correct scroll position, we add the class show and that triggers the animation performed by CSS and not javascript, as we have the transition property for the property right defined - that way the browser does the heavy lifting.
Toggling show/hide alters your elements width. You either have to put it in a container with display: inline
Or more ideally you might want to change show/hide to jQuery fadeIn() / fadeOut() which is more appropriate for "Back to Top" indicators.
Here is your codepen example modified with inline container:
http://codepen.io/anon/pen/MwWweY

Updating button text with sliding text from top

I am trying to update a button text on click by sliding the new text from the top. It "pushes" the text and appear.
I've managed to do that, but when the background is darker, we can see the text appearing outside the button. How to solve that ? And i can't lower the top value since otherwise the text is still visible when it is removed from the DOM. Here is my code:
var i = 1;
$('a').on('click', function (event) {
var $el = $(this);
$('span').animate({
'top': '+=20px'
}, 250, function () {
$el.html('');
i++;
$el.prepend('<span class="b" >' + i + '</span>');
$('.b').animate({
'top': '+=20px'
}, 250);
});
});
CSS :
span {
position: relative;
}
.b {
top: -20px;
}
JSFiddle here
Is there a way to cut the text when it is bigger than the container ?
Like so:
Use overflow: hidden on the a tag.
http://jsfiddle.net/QG4cx/12/
a {
overflow: hidden;
}

Tooltip does not display when anchor is out of normal flow

On my site, I use DOM nodes of class="trigger" as anchors for tooltips. When the mouve hovers these anchors, a tooltip displays. The jQuery code generating the tooltip container is as follows:
$('.trigger').mouseover(function() // OnMouseOver event
{
$("<div/>", {
id: "tooltip",
css: {
display: "none",
position: "absolute",
border: "3px solid #111",
color: "#000",
padding: "5px",
opacity: 1.0,
fontSize: "15pt",
backgroundColor: "#fff",
borderRadius: "15px",
zIndex: 3000
}
}).appendTo(this);
$("#tooltip").html($(this).attr('title'));
$(this).attr('title',''); // empty the title attribute of the anchor (avoiding default browser reaction)
$('#tooltip').show(); // show the tooltip
}).mousemove(function(e) // OnMouse mode event
{
$('#tooltip').css('top', e.pageY + 20); // tooltip 20px below mouse poiunter
$('#tooltip').css('left', e.pageX - 20); // tooltip with mouse pointer
}).mouseout(function() // OnMouseOut event
{
$(this).attr('title',$('#tooltip').html()); // set the title back to initial value
$(this).children('div#tooltip').remove(); // get rid of the tooltip container
});
It works very well when the anchor is positioned in the normal flow of the page but it does not display when the anchor is out of the flow as in
$("<img/>", {
id: "arrowup",
class: "trigger noprint",
css:{
display:"none",
position:"fixed",
bottom:'15px',
right:'10px',
cursor: "pointer"
},
src:"../images/arrowup.jpe",
alt:"vers le haut",
title: "Haut de la page",
click:function(){
$("html, body").animate({scrollTop: "0px"}, 800);
return false;
}
}).appendTo("body");
$(window).bind("scroll", function() {
var obj = $("#arrowup");
if ($(this).scrollTop() > 300){
obj.fadeIn(800);
} else {
obj.fadeOut(800);
}
});
Is this normal behaviour or is there a trick to get the tooltip displayed normally?
If I understood your question right, you need to wrap your image with fixed div:
<div class="fixed">
<img src="http://placehold.it/150x150">
<div class="tooltip">Tooltip</div>
</div>
And CSS:
.fixed {
position: fixed;
bottom: 20px;
right: 20px;
}
.tooltip {
position: absolute;
left: -50px;
top: 0;
display: none;
}
.fixed:hover .tooltip {
display: block;
}
Check JSFiddle
Hover over placeholder to see tooltip.
When you add content dynamically to the page after dom load you need to let javascript know you have done so.
This is done by event propagation. If your triggers are contained within a parent div do this:
$('#parent').on('mouseover', '.trigger', function() {
//your code here.
});
The following code works!
$('.trigger').mouseover(function(){ // OnMouseOver event
$("<div/>", {
id: "tooltip",
css: {
display: "block",
position: "absolute",
border: "3px solid #111",
color: "#000",
padding: "5px",
opacity: 1.0,
fontSize: "15pt",
title: "XXX",
backgroundColor: "#fff",
borderRadius: "15px",
zIndex: 3000
}
}).appendTo("body");
$("#tooltip").html($(this).attr('title'));
$(this).attr('title',''); // empty the title attribute of the anchor (avoiding default browser reaction)
$('#tooltip').show(); // show the tooltip
}).mousemove(function(e) // OnMouse mode event
{
$('#tooltip').css('top', e.pageY + 20); // tooltip 20px below mouse poiunter
$('#tooltip').css('left', e.pageX - 20); // tooltip with mouse pointer
}).mouseout(function() // OnMouseOut event
{
$(this).attr('title',$('#tooltip').html()); // set the title back to initial value
$("body").children('div#tooltip').remove(); // get rid of the tooltip container
});
and note that the only modification made to it is that the div#tooltip is now located in the body rather than as a child of its anchor.
Why does this make it work? I really don't know.
On my site, I use DOM nodes of class="trigger" as anchors for tooltips. When the mouve hovers these anchors, a tooltip displays and moves with the mouse motion. The jQuery code generating the tooltip container was modified as follows:
$("#template").on("mouseover", ".trigger", function(){ // OnMouseOver event
$("<div/>", {
id: "tooltip",
css: {
display: "block",
position: "absolute",
border: "3px solid #111",
color: "#000",
padding: "5px",
opacity: 1.0,
fontSize: "15pt",
title: "XXX",
backgroundColor: "#fff",
borderRadius: "15px",
zIndex: 3000
}
}).appendTo("body");
$("#tooltip").html($(this).attr('title'));
$(this).attr('title',''); // empty the title attribute of the anchor (avoiding default browser reaction)
$('#tooltip').show(); // show the tooltip
}).on("mousemove", ".trigger", function(e){ // OnMouse mode event
$('#tooltip').css('top', e.pageY + 20); // tooltip 20px below mouse poiunter
$('#tooltip').css('left', e.pageX - 20); // tooltip with mouse pointer
}).on("mouseout", ".trigger", function(){ // OnMouseOut event
$(this).attr('title',$('#tooltip').html()); // set the title back to initial value
$("body").children('div#tooltip').remove(); // get rid of the tooltip container
});
Following Edward's suggestion, all $(".trigger").event(function() {...}); were replaced by $("#parent).on("event", ".trigger", function() {...}); so that jQuery would be aware of content added dynamically to the DOM after DOM ready. This new content is generated as follows:
$("<div/>", { // creates a container <div> for the arrowup image
id: "arrowup",
class:"trigger no_underline", // is an anchor for tooltip
css:{
display:"none",
position:"fixed",
bottom:"30px",
right:"30px",
cursor: "pointer"
},
click:function(){ // assign page up functionality
$("html, body").animate({scrollTop: "0px"}, 800);
return false;
},
title: "Haut de page" // title to be passed to the tooltip
}).appendTo("#template");
$("<img/>", { // creates the image and its functionality
src:"../images/arrowup.jpe",
alt:"vers le haut",
}).appendTo("#arrowup");
$(window).bind("scroll", function() { // shows tooltip only when page is scrolled
var obj = $("#arrowup");
if ($(this).scrollTop() > 300){
obj.fadeIn(800);
} else {
obj.fadeOut(800);
}
});
In the original listings, each of the .trigger have been individually given instructions. If new .trigger are created, they won't have heard the instruction and won't respond to mouseover, mousemove and mouseout events, each of them being directly responsible for their own events. In the modified setting, only the container (here #template) has been given the instruction; it is responsible for noticing the events on behalf of its child elements. The work of catching events has been delegated.
Referring to Alexander's comment, in my question I was binding to the anchor position whereas I am now binding to the position of cursor at the time of tooltip firing: this is the behaviour that I expected.
3
When I asked the question, I believed that the non-show of the tooltip was related to the fact the the new element was out of the normal flow (position: fixed). It is not that at all.
Everything works as expected now! Thanks to all who helped me.

jQuery slideUp to show the element and not hide

jQuery's slideUp effect hides the element by sliding it up, while slideDown shows the element. I want to show my div using slideUp. can anyone guide me ? thanks
$("div").click(function () {
$(this).hide("slide", { direction: "down" }, 1000);
});
http://docs.jquery.com/UI/Effects/Slide
It's a little more complex than just saying slideUpShow() or something, but you can still do it. This is a pretty simple example, so you might find some edge-cases that need adressing.
$("#show-animate-up").on("click", function () {
var div = $("div:not(:visible)");
var height = div.css({
display: "block"
}).height();
div.css({
overflow: "hidden",
marginTop: height,
height: 0
}).animate({
marginTop: 0,
height: height
}, 500, function () {
$(this).css({
display: "",
overflow: "",
height: "",
marginTop: ""
});
});
});
Here's a fiddle showing the slideUp/slideDown methods, the same effects using animate, and a modified version using animate that goes in reverse: http://jsfiddle.net/sd7zsyhe/1/
Since animate is a built-in jQuery function, you don't need to include jQuery UI.
To get the opposite of slideUp and slideDown. Add these two functions to jQuery.
$.fn.riseUp = function() { $(this).show("slide", { direction: "down" }, 1000); }
$.fn.riseDown = function() { $(this).hide("slide", { direction: "down" }, 1000); }
I found a tricky way...
you can set div with css style bottom:0px,
add call
$("#div).slideDown();
will show with the slideUp-to-show effect you want.
Jquery toggle
This toggle effect is only for up and down. Jquery UI is for every other direction
For those who donĀ“t use the Jquery UI but want to add the function to Jquery Library:
jQuery.fn.slideUpShow = function (time,callback) {
if (!time)
time = 200;
var o = $(this[0]) // It's your element
if (o.is(':hidden'))
{
var height = o.css({
display: "block"
}).height();
o.css({
overflow: "hidden",
marginTop: height,
height: 0
}).animate({
marginTop: 0,
height: height
}, time, function () {
$(this).css({
display: "",
overflow: "",
height: "",
marginTop: ""
});
if (callback)
callback();
});
}
return this; // This is needed so others can keep chaining off of this
};
jQuery.fn.slideDownHide = function (time,callback) {
if (!time)
time = 200;
var o = $(this[0]) // It's your element
if (o.is(':visible')) {
var height = o.height();
o.css({
overflow: "hidden",
marginTop: 0,
height: height
}).animate({
marginTop: height,
height: 0
}, time, function () {
$(this).css({
display: "none",
overflow: "",
height: "",
marginTop: ""
});
if (callback)
callback();
});
}
return this;
}
Credits: #redbmk answer
Despite the name, slideDown can actually slide your element both ways. Use absolute position if it is required to animate inside the parent element:
#slideup {
position:fixed;
bottom:0;
background:#0243c9;
color:#fafefa;
width:100%;
display:none;
padding: 20px;
}
#littleslideup {
position:absolute;
bottom:0;
background:#000;
color:#fff;
display:none;
padding:10px;
z-index:100;
}
#slidedown {
position:fixed;
top:0;
background:#c94333;
color:#fafefa;
width:100%;
display:none;
padding: 20px;
}
button {
display:inline-block;
font-size:16px;
padding:10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="position:relative">This amounts to 70% of the total timber stand area of the region (not including the dwarf pine and shrubby alder) and is more than the total area of all other stone birch forests growing in the Magadan, Khabarovsk, Primorye and Sakhalin regions and other areas of its distribution.
<div id="littleslideup">Absolute-positioned element</div>
</div>
<span style="color:red">Click >> </span>
<button onclick="jQuery('#slideup').slideDown(1500);" >"Slideup"</button>
<button onclick="jQuery('#slidedown').slideDown(1500);" >"Slidedown"</button>
<button onclick="jQuery('#littleslideup').slideDown(1500);">"Slideup" inside element</button>
<div>Finally, closing the subject of volcanic activity, it must be said that the stone birch stands by its functional reaction quite adequately in order to re ect the character and intensity of the physical, chemical and thermic processes, stipulated by volcanism as well as the in uence upon biota and ecosystems.</div>
<div id="slideup">Could be a bottom cookie warning bar</div>
<div id="slidedown">Could be a top cookie warning bar</div>
I've got some downvotes so I checked my answer and indeed I didn't answered correctly the OP question, sorry. So I'm gonna try to fix that.
First, the slideUp() method in JQuery is intended to hide the element rather than reveal it. It is basically the opposite of slideDown() which shows your element by sliding it down.
By knowing that I think we agree that there is no magic function right there to do a slide up effect to show an element (in JQuery).
So we need to do a little bit of work to get what we need: slid up reveal effect. I found out some solutions and here is one I think simple to implement:
https://coderwall.com/p/9dsvia/jquery-slideup-to-reveal
The solution above works with the hover event, for the click event try this modified code:
http://jsfiddle.net/D7uT9/250/
The answer given by #redbmk is also a working solution.
Sorry for my misunderstanding the first time.
OLD ANSWER
It's an old post, but if someone is looking for a solution here is my recommandation.
We can, now, use slideToggle() to achieve this effect (without the need of jQuery UI).
$(".btn").click(function () {
$("div").slideToggle();
});
Documentation: http://api.jquery.com/slidetoggle/
Having encountered this with a student looking to "slide up always hide" an error container, I advised he simply use CSS transitions:
.slide-up {
transition: 1s ease-out;
transform: scale(1);
}
.slide-up[aria-hidden="true"] {
transform: scale(0);
height: 0;
}
jQuery(document).ready(function($) {
const $submitButton = $(".btn");
const $someDivs = $("div");
const $animatedSlidingTargets = $(".slide-up");
$someDivs.on("click", function() {
$animatedSlidingTargets.attr("aria-hidden", true);
});
});
For #Jason's answer, whether slide-up to show and slide-down to hide, you still need to use the { direction: "down" } option in jQuery:
$(".btnAbout").on("click", function () {
// Slide-up to show
$("#divFooter").show("slide", { direction: "down" }, 1000);
});
$("#btnCloseFooter").on("click", function () {
// Slide-down to hide
$("#divFooter").hide("slide", { direction: "down" }, 1000);
});
But this requires jquery-ui, or else you'll hit the TypeError: something.easing[this.easing] is not a function error:
<script defer src="https://code.jquery.com/ui/1.13.2/jquery-ui.min.js"></script>

Categories

Resources