first here is the JSFiddle I've been working on
http://jsfiddle.net/rastlin80/P53Le/
I've created a new plugin called sopopup
what is does is match an element as a pop-up that will appear around some text when the text is hovered.
it works correctly when the selector for the element that will be hovered is a single element
$('#message').sopopup({ target: $('#ho')});
the pop up appears right above the text, but when the selector has multiple items it always hovers over the first item.
$('#message2').sopopup({ target: $('.meds')});
my problem is in the code for the hover event.
settings.target.hover( //where target are the elements selected such as $('.meds')
function() {
//here is my problem the var this is not the target being hovered
//the var this is refering to the settings it seems
var pos;
var hgt;
if(settings.location === 'top'){
pos = settings.target.position();
//i wanted to do this.position() but that show an error
hgt = settings.pop.height();
settings.pop.css({
position: "absolute",
top: (pos.top - hgt) + "px",
left: pos.left + "px"
});
}
else if( settings.location === 'bottom'){
pos = settings.target.postion();
hgt = settings.target.height();
settings.pop.css({
position: "absolute",
top: (pos.top + hgt) + "px",
left: pos.left + "px"
});
}
settings.pop.show();
}.bind(settings)
I am unable to use the variable this to refer to the item that is currently being hovered over. instead the variable this within the hoverIn function seems to refer to the settings object.
any help appreciated.
This fork of your Fiddle uses a combination of $.each and setting a variable named self to reference the appropriate this (wrapped with jQuery) to achieve what I believe it is you're asking for:
$.each(settings.target, function(){
var self = $(this);
self.hover(function() {
var pos;
var hgt;
if(settings.location === 'top'){
pos = self.position();
[...]
Related
I want to display the popup on the top of element if there is no proper space on the top. Currently it hides inside the window as seen in the image below:
I can update the top position but I only want when there is no proper space otherwise it is ok.
Please let me know how to determine if the clicked position in near window edges.
JSFiddle Link :http://jsfiddle.net/g4g4negf/
Code I am using to get the position:
$(document).ready( function() {
$('.clickme').on('click', function(e) {
$('#popup').offset({ top: e.pageY, left: e.pageX}).fadeIn();
});
Check out this JSFiddle
To check if clicked position is near window edge, you have to get window's height ($(window).height()) and scroll position (window.pageYOffset). By adding these two values, you can find the scrolled position of the window. Then compare this sum with e.pageY+$("#popup").height() (this is the sum of the clicked position's height and the popup's height). If the latter is less than the former, it means the popup can be shown. If (e.pageY+$("#popup").height())>($(window).height()+window.pageYOffset) it means the popup will overflow the window's bottom border, then its top offset should be changed to e.pageY-$('#popup').height().
Here is the complete function:
$('.clickme').on('click', function(e) {
var h;
if((e.pageY+$('#popup').height())<($(window).height()+window.pageYOffset)) h=e.pageY;
else h=e.pageY-$('#popup').height();
$('#popup').offset({ top: h, left: e.pageX}).fadeIn();
});
Considering your popup height is 100px, you can try this...
$(document).ready( function() {
var h = window.innerHeight;
$('.clickme').on('click', function(e) {
alert(h + ", " + e.pageY);
if( h - e.pageY < 125) {
$('#popup').offset({ top: h-125, left: e.pageX}).fadeIn();
}
else {
$('#popup').offset({ top: e.pageY, left: e.pageX}).fadeIn();
}
});
});
I'm using Packery JS to create a card lay-out. In this lay-out I move things around using the fit method. When the moving is finished I then scroll to the moved div; I wait for the fit complete event and then use jQuery's scrolltop to scroll to the div in question. This is the code I currently use for the scrolling part:
$container.packery( 'on', 'fitComplete', function () {
$('html,body').animate({
scrollTop: $("#" + moveItem).offset().top - 40
});
console.log("scroll to: " + moveItem + ", position: " +($("#"+moveItem).offset().top - 40))
});
On the first click this works as intended, this is the output of moving div#vision:
scroll to: vision, position: 69
But on the second click (moving div#project-6) it goes wrong:
scroll to: project-6, position: 616
scroll to: vision, position: 69
It first scrolls to project-6, but then immediately goes to the previous value of moveItem, vision. On subsequent clicks the list only gets longer.
So my question: Why is it remembering the previous values of the moveItem variable? And how can I stop it from doing that?
For context, this is the website I'm using it on. The code in question can be found by searching for "//Move function".
Thanks in advance!
This happens when you execute $container.packery( 'on', ...); several times. My guess is that you attach another event handler every time you click the button instead of attaching it once in the setup of the page and then make sure the event is triggered when the button is clicked.
I will be more specific. Change this function to this:
//Move Function
var moveThis = function(moveItem, moveTarget){
if (moveTarget == "stamp" && $("#" + moveItem).hasClass("w2") && 720 < window.innerWidth && window.innerWidth < 992) {
var targetX = 0;
var targetY = $("#stamp").height() + 40;
$container.packery('fit', document.getElementById(moveItem), targetX, targetY);
} else if (moveTarget == "stamp") {
var arrayList = $container.packery('getItemElements')
var targetX = $(arrayList[0]).position().left
var targetY = $(arrayList[0]).position().top
$container.packery('fit', document.getElementById(moveItem), targetX, targetY);
} else {
var arrayList = $container.packery('getItemElements')
positionList = arrayList.indexOf(document.getElementById(moveTarget))
var targetX = $(arrayList[positionList+1]).position().left
var targetY = $(arrayList[positionList+1]).position().top
$container.packery('fit', document.getElementById(moveItem), targetX, targetY);
}
};
this code must be out of function, somewhere globally defined:
$container.packery( 'on', 'fitComplete', function ( moveItem ) {
$('html,body').animate({
scrollTop: $("#" + $(moveItem.element).attr('id')).offset().top - 40
});
console.log("scroll to: " + $(moveItem.element).attr('id') + ", position: " +($("#"+moveItem).offset().top - 40))
});
I'm not sure about $(moveItem.element).attr('id') - for this look at console what it has
I'm trying to get a large logo (in the header of my site) to fall down into the header area on load. And so this is the only jquery function that I can find that seems to fit the idea.
http://jsfiddle.net/apHLu/279/
var $dropDiv = $('#dropDiv');
$('#holder a').on('click', function() {
// get position of the element we clicked on
var offset = $(this).offset();
// get width/height of click element
var h = $(this).outerHeight();
var w = $(this).outerWidth();
// get width/height of drop element
var dh = $dropDiv.outerHeight();
var dw = $dropDiv.outerWidth();
// determine middle position
var initLeft = offset.left + ((w/2) - (dw/2));
// animate drop
$dropDiv.css({
left: initLeft,
top: $(window).scrollTop() - dh,
opacity: 0,
display: 'block'
}).animate({
left: initLeft,
top: offset.top - dh,
opacity: 1
}, 300, 'easeOutBounce');
});
I basically want to know, is it possible to switch the click trigger to an onload call? I don't want to be muddling around trying to get it to work if it's not possible.
Thank you.
Here is an updated Fiddle. $(function() { ... }); is short for 'Document is ready'. I also wrapped the function in setTimeout();, because it was firing a little quick to see the full effect. Change the second parameter in setTimeout to adjust the time it waits to fire...
Updated (per #coby suggestion): If you do have a large amount of images you could change $(function() { to window.onload(function() {. Ready doesn't wait for all the images to be completely loaded.
I have a div with the attribute position: relative;. Now, there are three of these divs. They all get a unique ID etc.
Now if I click a div, I want it to animate to a certain position in the document. Although I cannot determine the left/top values since if I use "top" and "left", it will relatively set the left to its parents position.
Maybe a bit unclear, but here is what I got.
The CSS of the clickable DIV that will move.
div#left_hldr .switch_project {
z-index: 1001;
position: relative;
margin: 10px 0px 0px 0px;
cursor: pointer;
}
// Open project.
$(".switch_project").live('click', function() {
// Get the ID value.
var More_Id = $(this).attr("id");
// Explode the Id.
var Id_Split = More_Id.split("_");
// Get the project ID.
var Project_Id = Id_Split[2];
/*
Replacement of the switch project div.
1 ) Define the current position.
2 ) Define the new position.
3 ) Replace the DIV to the new position.
4 ) Fade the new page in.
5 ) Put the DIV back to its original position.
*/
// Current Position.
var Ori_Left = $(this).offset().left;
var Ori_Top = $(this).offset().top;
// New Position. [ Based on the content_hldr container ]
var New_Top = $("div#content_hldr").offset().top;
var New_Left = $("div#content_hldr").offset().left;
// Define the current div.
var Div_Rep = $(this);
// Hide the More Info tab.
$(Div_Rep).children(".more_info").fadeOut("fast");
// Fade content out.
$("div#content_hldr").fadeOut("fast");
// Replace the div.
$(Div_Rep).animate({
top: New_Top,
left: New_Left
}, "slow", function() {
// Load Home page in.
$("div#content_hldr").load("content/content.projects.php?id=" + Project_Id, function() {
// Re-define Cufon.
Cufon.replace('h2');
});
// Fade in the content.
$("div#content_hldr").fadeIn("fast", function() {
// Hide the replaced div.
$(Div_Rep).hide();
// Replace it back to its position.
$(Div_Rep).css({
top: Ori_Top,
left: Ori_Left
});
// Show the More Info tab again.
$(Div_Rep).children(".more_info").show();
// Fade back in.
$(Div_Rep).fadeIn("medium");
});
});
});
...it will relatively set the left to its parents position.
Actually, no. If you use left and top with a position: relative element, they'll offset it from where it otherwise would be if it weren't positioned (e.g., in the static flow), while continuing to reserve its space in the static flow. A subtle but important distinction (and hugely useful for drag-and-drop).
If you want to animate it to the top left of the document, you can figure out its offset (via offset), and then provide those as negative numbers for left and top, since of course if it's at (say) [100,50], then positioning it at [-100,-50] compared to its default position will...put it at [0,0].
Like this:
$("selector_for_your_divs").click(function() {
var pos, $this;
$this = $(this);
pos = $this.offset();
$this.animate({
left: "-" + pos.left + "px",
top: "-" + pos.top + "px"
});
});
Live example
Similarly, if you want to move it to be where another element is, simply subtract its position from the other element's position — that gives you the delta to apply:
$("selector_for_your_divs").click(function() {
var mypos, otherpos, $this;
// Move to the target element
$this = $(this);
pos = $this.offset();
otherpos = $('selector_for_other_element').offset();
pos.left = otherpos.left - pos.left;
pos.top = otherpos.top - pos.top;
$this.animate({
left: pos.left + "px",
top: pos.top + "px"
});
});
Live example
I have a table & when I click a cell, it displays a DIV(to the right of the mouse) with absolute positioning.
I want the DIV to display using minus co-ords(positioning), so it never display outside the table('#holiday-planner-table') .
Here's the concept I'm thinking of:
if($('#DayInfo'). is outside of $('#holiday-planner-table')) {
display $('#DayInfo') with minus co-ordinates
} else
{
$(".WeekDay").click( function(event) {
$("#DayInfo").css( {position:"absolute", top:event.pageY, left: event.pageX} );
});
}
It's not a complete solution but you can use $("selector").offset().left or top and $("selector").width() or height to construct two rectangles, check if one is not inside the other and act accordingly.
the logic here is to check if the new div coordinates put the div position + size outside the table position + size. if it will, you set the div coordinates back the size of the div. you can do left and top independently.
this should get you pretty close:
$(".WeekDay").click(function (e) {
var x = e.pageX;
var y = e.pageY;
var $div = $('#DayInfo');
var $table = $('#holiday-planner-table');
if (x + $div.width() > $table.offset().left + $table.width()) {
x -= $div.width();
}
if (y + $div.height() > $table.offset().top + $table.height()) {
y -= $div.height();
}
$div.css({ position: "absolute", top: y, left: x });
});
I'm thinking of something among the lines of:
if (mousex > (tablew-divw)) divx = mousex-divw
else divx=mousex
same thing goes for Y.
Of course, that could mess stuff up if the table actually becomes smaller than the div.
I could be wrong, but are you wanting to create some sort of tooltip functionality? If so, have a look at http://flowplayer.org/tools/tooltip/index.html