How to dynamically display position of a div on hover - javascript

Hi i am creating a website in wordpress,where i am using javascript to display a description div on hover a list of elements but my problem is according to screen size the description div must vary its position in order to display the content completely.I am not sure that i expressed my query clearly could anyone suggest me how can i get this.
jQuery:
(function($) {
$(document).ready( function() {
$('#linkcat-4 .xoxo li:nth-child(1)').mouseover(function(e) {
$('#text1').css(
'visibility' , 'visible'
);
$('#linkcat-4 .xoxo li:nth-child(1)').mouseout(function(e) {
$('#text1').css(
'visibility' , 'hidden'
);
});
});
});
})(jQuery);
HTML:
<ul class="xoxo blogroll">
<li>Admirality</li>
<li>Banking</li>
<li>Commercial</li>
<li>Contract</li>
<li>test</li>
<li>Corporate</li>
</ul>
<div class="desc-text" id="text1" style="visibility: hidden;">
<p>We represent protection and indemnity clubs that provide insurance
for many of the ships coming to Guyana. We deal with all the familiar
problems encountered by ships, both contentious and non-contentious,
including arrests arising from accidents and claims for wages and damaged
cargo. We advise masters, obtain surveys, note protests, negotiate
settlements and advise on or deal with stowaways and medical emergencies.
Our admiralty practice is the largest in Guyana.
</p>
</div>
CSS:
.desc-text {
position: absolute;
top: 12%;
left: 50%;
}
#text1 {
visibility:hidden;
background:#f1f1f1;
padding: 15px;
width: 150px;
}

You need to check the window.innerHeight and window.innerWidth properties before setting the top and left of your popup div. Here is a fiddle to get you started.
The important part is inside the .hover() call:
$( function() {
pop = $("#popup");
$(".item").hover( function() {
row = $(this);
pop.html(row.data("extra"))
.css("top", (function(r) {
if(r.offset().top > window.innerHeight - pop.height())
return window.innerHeight - pop.height();
else
return r.offset().top;
})(row))
.css("left", (function(r) {
if(r.offset().left + r.width() > window.innerWidth - pop.width())
return window.innerWidth - pop.width();
else
return r.offset().left + r.width();
})(row))
.show();
}, function() {
pop.hide();
});
});
Basically, .hover() takes two functions, one for mouseover and one for mouseout. On mouseout, I just hide the popup. On mouseover, I fill the popup div with content (here coming from the item's data-extra attribute, but it could come from anywhere) then decide where to put it based on the location of the item and the window bounds.
Hope that helps. Leave a comment if you need more.
Update
So, the short answer is to make your content fit a normal browser window. I have to maximize my browser to be able to see everything in that popup. It seems like important information, too. So maybe it deserves its own page? These are opinions, not facts, so I'll move on to the latest version of the fiddle which you can more easily look at here.
There were changes to make everywhere, in the CSS, HTML, and Javascript, to make this work. Probably the biggest issue is visibility:hidden. There might be a way to get jQuery to work with that, but I just use the default display:none, which is what .show() and .hide() toggle.
New css
#text1
{
display:none;
background:#f1f1f1;
padding: 15px;
width: 150px;
}
And I needed to wrap your ul with a div of id linkcat-4. Now for the new js. The most interesting change is that I realized we need to take the div's padding into account. Since the padding parameter applies to all sides, we actually need to double the padding and add that to our offset from the window bounds:
New javascript
(function($) {
$(document).ready( function() {
var pop = $("#text1");
$('#linkcat-4 .xoxo li:nth-child(1)').hover(function(e) {
var row = $(this);
pop.html(row.data("extra"))
.css("top", (function(r) {
if(r.offset().top > window.innerHeight - pop.height())
return window.innerHeight - pop.height() - parseInt(pop.css("padding"))*2;
else
return r.offset().top;
})(row))
.css("left", (function(r) {
if(r.offset().left + r.width() > window.innerWidth - pop.width())
return window.innerWidth - pop.width() - parseInt(pop.css("padding"))*2;
else
return r.offset().left + r.width();
})(row))
.show();
},
function(e) {
pop.hide();
});
});
})(jQuery);
Let me know if that works.

Related

JQuery - Position Popup in relative to button(s)

I'm trying to position a popup relative to its button or the button that is clicked with jquery. I'd like to position the popup in a way that doesn't cover up the button itself. Position it to the left, right, above or below the button that is clicked.
Now I know I can do this by writing more html popups and css but there got to be a way to dynamically use one div and position it with jquery. I tried using offsets and position (at one point) but I couldn't get it to work. Frankly, I'm very entry level with js and jquery so forgive my noobness.
Any help would be greatly appreciated!!
JS:
$('.trends').click(function () {
$('.questions').fadeIn();
$('.question').html('<p>What trends could potentially drive growth in the U.S.?</p>');
/* if I add this and zero out the positioning via css the pop gets offset but its way far away from this parent.
var offset = $(this).offset();
$('.questions').css('left',offset.left);
$('.questions').css('top',offset.top);*/
});
$('.consumer').click(function () {
$('.questions').fadeIn();
$('.question').html('<p>Even though we have low inflation, consumers are not increasing their spending. Why?</p>');
});
$('.industry').click(function () {
$('.questions').fadeIn();
$('.question').html('<p>What factors drove crude oil prices to fall and which industries benefited?</p>');
});
$('.henn').click(function () {
$('.questions').fadeIn();
$('.question').html('<p>MESSAGE FROM OUR PRESIDENT</p>');
var offset = $(this).offset();
$('.question').html('<p>What trends could potentially drive growth in the U.S.?</p>');
});
$('.equity').click(function () {
$('.questions').fadeIn();
$('.question').html('<p>The U.S. stock market has been rising for more than six years. What do you see ahead for equities?</p>');
});
$('.balance').click(function () {
$('.questions').fadeIn();
$('.question').html('<p>what does it look like for companies balance sheets?</p>');
});
$('.close').click(function (e) {
e.stopPropagation();
$(this).parent().hide();
$('.items').removeClass('no-effect');
});
jsFiddle
Create a separate function to display the question, which takes the clicked button and the question as parameters:
function showQuestion(button, question) {
var offset = button.offset();
$('.question').html(question);
$('.questions')
.fadeIn()
.css({
left: Math.min(offset.left, $(window).innerWidth()-$('.questions').outerWidth()),
top: offset.top + button.innerHeight()
});
}
Call it like this:
$('.trends').click(function () {
showQuestion(
$(this),
'<p>What trends could potentially drive growth in the U.S.?</p>'
);
});
Updated Fiddle
The css left calculation ensures that the question will always be on-screen.
Part of your problem was .filter being set to position: relative;.
If an absolute positioned element has a relative positioned parent the absolute element will be positioned in relation to the parent not the document.
If you remove that it gets a little easier to use .offset() to position the question:
Working Example
$('.trends').click(function () {
$('.questions').fadeIn();
$('.question').html('<p>What trends could potentially drive growth in the U.S.?</p>');
/* See change here*/
var offset = $(this).offset();
$('.questions').css('top', offset.top + $(this).height());
});
.filter {
width: 98.1481481481%;
float: left;
margin-left: 0.9259259259%;
margin-right: 0.9259259259%;
margin-bottom: 10px;
/*position: relative; see change here */
}
There's a $(...).position() function in jQuery that should help you out. I refactored your code a bit to avoid repeating lines, but the gist of it is:
function popup(jqBtn, question){
// mind that the .position does not account for borders etc.
var btn = $(jqBtn).parents('.buttons'),
posLeft = btn.position().left + btn.outerWidth(),
posTop = btn.position().top;
$('.questions').fadeIn();
$('.question').html(question);
$('.questions')
.appendTo(btn.parent())
.css('left', posLeft + 'px')
.css('top', posTop + 'px');
}
// a sample of binding a button to the popup() function
$('.trends').click(function () {
popup(this, '<p>What trends could potentially drive growth in the U.S.?</p>');
});
So the function re-appends the 'questions' div to have the same parent as the button. The button is found based on the element clicked, traversing up the structure to find an element of '.buttons' class. That might need adjusting if the structure gets more complex.
jsFiddle

jQuery - have popup box appear on screen regardless of how low they scroll

I'm trying to create a popup box on a list of items that goes very much to the bottom of the browser.
I want the POPUP to be in the center of the page where the user is at regardless of how low they scrolled
i have to use POSITION ABSOLUTE not FIXED
but when i use POSITION ABSOLUTE the popup always appears on top and i know its due to my top: 0
.lightbox-container{
border: solid red 1px;
width: 100px;
height: 40px;
background: yellow;
position: absolute;
top: 0;
}
I want to use something like scrollTop or one of those to get the popup to always stay in the users viewpoint regardless of how low they scrolled
$('a').on('click', function(e){
var lightBox = $('<div class="lightbox-container"> <p>click to remove</p>');
lightBox.appendTo('body');
$('.lightbox-container').on('click', function(e){
$(this).remove();
});
});
here is the fiddle im working on http://jsfiddle.net/2RNAN/1/
I know there are other posts about this but im very new to jquery and cant seem to get it working.
This works working fiddle here
$('a').on('click', function (e) {
e.preventDefault();
var lightBox = $('<div class="lightbox-container"> <p>click to remove</p>');
lightBox.appendTo('body');
$('.lightbox-container').css('top', $(document).scrollTop() + 'px');
$('.lightbox-container').on('click', function (e) {
$(this).remove();
});
});
$(document).on('scroll', function () {
$('.lightbox-container').css('top', $(document).scrollTop() + 'px');
});
Edit: I think its a bit unclean and also unnecessary to center the pop-up box via jQuery. You can easily do this with CSS. Check out my updated JsFiddle: http://jsfiddle.net/kCC8p/9/ Edit End
I set the overflow to hidden on the body and included the pop-up outside the scrollable element. This way the scroll position of the user doesn't matter anymore.
JS
var lightbox = $('.lightbox-container');
$('a').click(function(e) {
e.preventDefault();
lightbox.show();
lightbox.addClass('open');
lightbox.append('<p>Click to remove</p>');
});
lightbox.click(function(e) {
lightbox.removeClass('open');
lightbox.find('p').remove();
$(this).hide();
});
See rest on jFiddle...
I may be a little late but I think this might be closer to what you were after:
Working Example
$(function () {
var lightbox = $('.lightbox-container'),
center = function () {
var T = $(window).height() / 2 - lightbox.height() / 2 + $(window).scrollTop(),
L = $(window).width() / 2 - lightbox.width() / 2;
lightbox.css({
top: T,
left: L
}).click(function () {
$(this).hide();
});
};
$('a').click(function (e) {
e.preventDefault();
lightbox.show().text('Click to remove');
center();
});
$(window).scroll(center);
$(window).resize(center);
});
Note that this method centers the popup and keeps it centered regardless of scrolling or re-sizing.
Are you avoiding the use of position fixed due to IE9 compatibility or some other reason? Using position fixed is probably the simplest answer and then address whatever compatibility issue you're having with specific browsers, such as with this answer for IE9 regarding quirks mode.

JQuery UI sortable in a scrollable container - scroll position "jumps" when sorting

Please check this almost identical question first: jQuery Sortable List - scroll bar jumps up when sorting
I have exactly the same problem, only that I tried all the suggested solutions there with no luck
Here is the way to reproduce
create a sortable list
have it scrollable
scroll down
reorder items
scroll position "jumps" up
Here is the code (see also in JSFiddle)
Html
<ul id="panel" class="scroll">
<li class="content" style="background-color:red">item1</li>
<li class="content" style="background-color:green">item2</li>
<li class="content" style="background-color:blue">item3</li>
<li class="content" style="background-color:gray">item4</li>
<li class="content" style="background-color:yellow">item5</li>
</ul>​
JavaScript
$(function() {
$("#panel").sortable({
items: ".content",
forcePlaceholderSize: true
}).disableSelection();
$(".content").disableSelection();
});​
CSS
.scroll{
overflow: scroll;
border:1px solid red;
height: 200px;
width: 150px;
}
.content{
height: 50px;
width: 100%;
}
​
Here is the code (in JSFiddle) after trying the notion of the accepted answer (with no luck)
I can try to understand why it happens (list get's "shortened" for a quick second), but all attempts to use placeholders or helpers to avoid it didn't work either. I feel I tried almost any permutation of the "scrollable" options with no luck
Browsers I tried
IE9, Firefox 10.0.1, and Chrome 17
JQuery versions
core 1.7.1, UI v 1.8.17
Am I doing something wrong? Is there a solution? Could it be a bug?
If you modifiy your CSS for the .scroll element by adding:
position:relative;
That should resolve this issue.
Adding overflow-y:scroll to the sortable list even without the height property solved it for me. It only shows a disabled scrollbar, but that's okay.
아래로 스크롤 할때 는 이런식으로 하면 됩니다.
var cY = -1;
var base = 0;
$("").sortable({
sort: function(event, ui) {
var nextCY = event.pageY;
if(cY - nextCY < -10){
if(event.clientY + ui.helper.outerHeight(true) - 20 > document.body.clientHeight) {
base = base === 0 ? event.clientY : base;
var move = event.clientY - base;
var curScrollY = $(document).scrollTop();
$(document).scrollTop(curScrollY + move+3);
base = event.clientY;
}
}
},
// .....
});
Seems like jQuery UI 1.9.2 solved the issue.
If you are unable to change the library, there's a workaround including a simple scroll bar operation. The idea is simple:
Keep the previous scroll position every time you scroll.
Set scroll back to the previous position when you start dragging your element.
Here you go;
var lastScrollPosition = 0; //variables defined in upper scope
var tempScrollPosition = 0;
window.onscroll = function () { // Up to you requirement you may change it to another elemnet e.g $("#YourPanel").onscroll
clearTimeout($.data(this, 'scrollTimer'));
$.data(this, 'scrollTimer', setTimeout(function () {
tempScrollPosition = lastScrollPosition; // Scrolls don't change from position a to b. They cover some numbers between a and b during the change to create a smooth sliding visual. That's why we pick the previous scroll position with a timer of 250ms.
}, 250));
lastScrollPosition = $(document).scrollTop(); // Up to you requirement you may change it to another elemnet e.g $("#YourPanel").onscroll
};
$("#YourSortablePanel").sortable({
start: function (event, ui) {
$(document).scrollTop(tempScrollPosition);
}
});
This is caused by the height of the container changing when sorting (just before the placeholder is created)
The problem is well described and answered in this stack overflow : https://stackoverflow.com/a/32477389/2604980
For me this sortable options were working if you don't want to remove overflow css from body:
start(e, ui) {
if (fixOffset) ui.item.css('transform', `translateY(${document.body.scrollTop}px)`);
fixOffset = true;
},
change(e, ui) {
ui.item.css('transform', `translateY(${document.body.scrollTop}px)`);
},
stop(e, ui) {
ui.item.css('transform', 'translateY(0)');
},

Scrollable ul list up and down from links with classes

I want to scroll a news article list up and down depending on which buttons is clicked
I wanted to adapt this way of animating if possible:
function smoothAdd(id, text)
{
var el = $('#scroller' + id);
var h = el.height();
el.css({
height: h,
overflow: 'hidden'
});
var ulPaddingTop = parseInt(el.css('padding-top'));
var ulPaddingBottom = parseInt(el.css('padding-bottom'));
el.prepend('<li>' + text + '</li>');
var first = $('li:first', el);
var last = $('li:last', el);
var foh = first.outerHeight();
var heightDiff = foh - last.outerHeight();
var oldMarginTop = first.css('margin-top');
first.css({
marginTop: 0 - foh,
position: 'relative',
top: 0 - ulPaddingTop
});
last.css('position', 'relative');
el.animate({ height: h + heightDiff }, 1500)
first.animate({ top: 0 }, 250, function() {
first.animate({ marginTop: oldMarginTop }, 1000, function() {
last.animate({ top: ulPaddingBottom }, 250, function() {
last.remove();
el.css({
height: 'auto',
overflow: 'visible'
});
});
});
});
}
$('.scrollUp').click(function() {
smoothAdd('scrollUp', 'A new item');
});
Example here: http://www.fiveminuteargument.com/blog/scrolling-list
My HTML looks like this:
<ul id="scroller">
<li class="current"><span>/</span>News Article Title</li>
<li><span>/</span>News Article Title 2</li>
<li><span>/</span>News Article Title 3</li>
</ul>
<div class="btnWrap"><p>Scroll Up
Scroll Up</p></div>
Can anyone point me in the right direction?
Basically maintain the animation style but keep it as a defined UL as per a normal carousel.
Here : http://jsfiddle.net/sDedY/13/
I've written form scratch. as you notice I've added css directly in a css file, it's better than adding css via jquery, especially for future mainenance/ decorateion etc.., but I havent spent much time for different caluclations. This is a blueprint I guess, you can modify and make it much better, like make top and bottom combined to make the function small or things like that, i jsut dont have time anymore ... so again : redo the calculations based on css yourself and modify it !
EDIT : regarding variable height, you need to keep in mind that I haven't finalised the whole function. next step in coding this function would be auto-calculation of margin-top and top rather than manually entering them, which is pretty easy. all that's needed is to pass a variable to get the position and dimensions of li elements and then pass them to our code.
I've change a few lines of your code:
var el = $('#scroller' + id); to var el = $('#' + id);
and
smoothAdd('scrollUp', 'A new item'); to smoothAdd('scroller', 'A new item');
see http://jsfiddle.net/nCWAP/
I made a slightly simpler solution. Check it out here
You don't need to mess with absolute or relative position neither with top. The list has height as auto so it grows/shrinks according to the height of their li elements
EDIT
Now the height is automatically adjusted to show all items.
Also supports li elements of any height.

Weird height doubling bug on mouseover with jQuery

i have used jquery and javascript to create some custom rollover button functionality and i am experiencing an issue where a variable is not be overwritten but added to. The basic function of my code is on mouseover of a link, i simply want the link to slide up and double in height so that the bottom 'on' portion of the graphic is showing (exactly like css sliding doors rollovers).
However the issue i am having is that the doubleHeight variable is cumulative so that every time you roll over the link the double height of the link is not reset each time, it just adds it to the last value. Weirdly this is only happening after a lightbox is triggered on the page, before that the functionality works just fine. Here is my javascript:
var heightVal, doubleHeight;
$('div.flex_rollover_btn p a').bind('mouseover', function() {
heightVal = $(this).css('height');
doubleHeight = heightVal.replace("px", "");
doubleHeight = doubleHeight * 2 + "px";
$(this).css({height: doubleHeight, top: '-' + heightVal});
});
$('div.flex_rollover_btn p a').bind('mouseout', function() {
heightVal = $(this).parent().css('height');
$(this).css({height: heightVal, top: '0'});
});
and here is the HTML code it is acting upon:
<div style="position: absolute; top: 322px; left: 13px; width: 139px; height: 79px; z-index: 3;" class="block item_3 flex_rollover_btn">
<p style="width: 75px; height: 53px;"><a style="width: 75px; height: 53px;" class="new_window" title="Flexible Size Rollover Test 2" href="http://doctype.tv"><img height="106" width="75" alt="Flexible Size Rollover Test 2" src="/cms/arcadiacorp_uk/repository/pages/static/static-0000006614/images/flex_rollover_2.gif"></a></p>
</div>
To see it in action go here scroll to the right and mouse over the red star thing, then open a lightbox (any of the links with the + symbol next to them) close it and mouseover the red star thing again and you will see what i mean.
In your mouseout handler function, you don't actually do anything. You get the heightVal (which was doubled earlier) and assign it back. The simple solution is to devide the value by two before assigning, just like you double it in the mouseover function.
The best way is to do it all with CSS classes. In CSS you specifiy all dimensions like height and then in JavaScript you can simply change the height by adding or removing a class.
Edit: I see in the mouseout handler function you look at the parent. Are you sure the parent isn't resized with the child element?
I know this isn't directly addressing your question, but don't do this:
doubleHeight = heightVal.replace("px", "");
doubleHeight = doubleHeight * 2 + "px";
Instead, do this:
doubleHeight = (2 * parseInt(heightVal, 10)) + px;

Categories