I have been trying to create a menu panel with jQuery that can be seen here by clicking the Preview button on top:
$(function(){
// hide all panels first
$('div[id*="panel"]').hide();
// make the panels absolute positioned
$('div[id*="panel"]').css('position', 'absolute');
// show the panel based on rel attribute of the current hovered link
$('#menu a').hover(function(){
var link_rel = $(this).attr('rel');
//get the position of the hovered element
var pos = $(this).offset();
// set z-index of previous panels low
$('div[id*="panel"]').css('z-index', '0');
// get the panel near by hovered element now
$('div#' + link_rel).css({
'left': pos.left + 'px',
'top': pos.top + 'px',
'zIndex': '5000'
});
// finaly show the relevant hidden panel
$('div#' + link_rel).fadeIn('slow');
// hide it back when mouse arrow moves away
$('div#' + link_rel).hover(function(){}, function(){
$(this).fadeOut('slow');
});
}, function(){});
});
http://jsbin.com/amexi/edit
If you hover over Link Two or Link Three, the black panel comes perfectly replacing the respective blue link, however if you hover the Link One, the black panel comes little below that link. What's wrong here? How can I fix this?
You need to account for the margin automatically applied to <ul> elements.
If you look at your page with Firebug, you'll notice Firefox applies a top and bottom margin of 16px.
As stated above, you can apply a margin-top value of -16px to the .left class to get your intended behaviour.
http://jsbin.com/amexi/3/edit
Check out http://jsbin.com/amexi/5/edit
I just can't figure out why the TOP is identical on all the popups BUT the actual position of them all is different. Makes no sense. Its almost like a negative margin.
The main problem I found is that you didnt move the popup into the position of the link + offset it to the .top + .height.
Related
I just used this code to get my menu highlighted as I scroll down to each each section of my WordPress site:
(function($) {
$(document).ready(function(){
$("header nav ul").toggleClass("open");
$("section.container").addClass("section");
});
$(window).scroll(function() {
var position = $(this).scrollTop();
$('.section').each(function() {
var target = $(this).offset().top;
var id = $(this).attr('id');
if (position >= target) {
$('#primary-menu > li > a').removeClass('active');
$('#primary-menu > li > a[href=#' + id + ']').addClass('active');
}
});
});
}(jQuery));
css:
.active{
color: #fff !important;
}
Here is the link: http://scentology.burnnotice.co.za
Problem is that the last item(Contact) is not getting highlighted when I scroll all the way down up to contact section.
Also,if I click on a menu item,it goes to the respective section but that menu doesn't get highlighted unless I scroll the page a little bit down'.
How can I solve that?
Thanks in advance
NOTE: It seems that you took that code from my answer to this SO question, I have edited it to cover your case. Other people looking for more code can check it out for a snippet.
So, you have two problems:
The last item is not getting highlighted.
When clicking on a menu item, the page scrolls to the respective section but that menu doesn't get highlighted unless scrolling down the page a little bit.
Problem 1
This one is easy, you just forgot to add the id attribute to the last section :)
It should be:
<section id="contact" class="container contact-us section">
Problem 2
Your click event starts a scroll animation to the corresponding section but, since the navigation bar is on the top of the page, you made the animation to leave a little margin on the top. That margin prevents the section from reaching the top of the page, so the menu item doesn't get highlighted.
#Shnibble pointed you in the right direction, you can add a small positive margin to the value returned by $(window).scrollTop() (or a negative one to the offset().top of the element).
So, following the code you have included, it will be something like:
if (position + my_margin >= target) {
The margin could be the height of your navigation bar:
my_margin = $('#site-navigation').height();
You can, obviously, add a little more or less to tailor it to your needs.
There is a simple solution and it just requires a bit of additional math :)
You are measuring from the top of the (window) viewport and checking to see if it is greater than or equal to the top of a specified target div. Because your content sections are exactly 100% of the viewport, it is impossible for the top of the viewport ever be greater than or equal to the top of the last content div.
What you need to do is offset the point you are measuring from so that you are not measuring from the top of the viewport, but rather some ways down from the top, say halfway or 3/4 of the way down. This will solve both of your issues.
Edit: here is something to get you started, then play around with dividing the window height by 1/2 or something like that:
var position = $(this).scrollTop() + $(window).height;
I have a grid of same height tiles that can be expanded on click. To make the rest of the div's stay in their position when one is expanded, I gave it margin-bottom: -100px.
However, when a div expands, all below him, just for a second, change their position, after that they come back.
I though about setting a fixed position for each of them using JS, but then I realized that I need the page to be resizeable, so I cannot execute Javascript every time.
Could you give me any advises on how to make a div overlay his neighbors without changing their position?
JSfiddle
So, I looked at your code and found the error. The CSS code hosts a margin-bottom of -256px. Basically, you are getting that bounce back everytime you click on a div you are pulling your content above the top clicked content by 256 pixels. To check for yourself I have made the adjustments showing you what 256px looks like on the class .posts-container .post-single.expanded(here)
This is a simple fix, just get rid of the -256px and put 1px. I made the adjustment here(here)
Basically, I found that there is no way to have what I want at this moment, so involving some JS I got this:
$('.expand:has(.open:visible)').click(function()
{
var button, backdrop, postOriginal, post;
button = $(this);
backdrop = $('.backdrop');
postOriginal = button.parents('.post-single');
post = postOriginal.clone().addClass('expanded');
post.css(
{
top: ( postOriginal.position().top + $('.widget-container').scrollTop() ) + 'px',
left: postOriginal.position().left + 'px'
}
);
backdrop.fadeIn().before(post);
$(window).resize(function()
{
post.css(
{
top: ( postOriginal.position().top + $('.widget-container').scrollTop() ) + 'px',
left: postOriginal.position().left + 'px'
}
);
});
$('.backdrop, .expand:has(.notOpen:visible)').click(function(event)
{
$('.backdrop').fadeOut()
.prev().remove();
event.stopPropagation();
return false;
});
return false;
});
It clones the post tile, gives it an exact position as it's original and overlays it, so it looks like the post it expanded, but in fact it's just copied.
I really can't do a little thing. I want that div1 change it's position ON CLICK of div2 (note that div2 is inside of div1) and when clicking again div2, put div 1 to his original position. (If you could help me moving the div1 with a little animation it would be perfect).
I added my exemple to jsfiddle, where I want to change the "switcher"'s position on first click on "switcher-header", and when click second time "switcher-header" take "switcher" back to it's original position.
http://jsfiddle.net/mdx7dpeL/3/
You could have a variable to toggle the marginLeft, so one click you animate left, and the other click you animate right:
var switched = false;
$(document).ready(function() {
$('.switcher-header').click(function() {
var marginLeft = switched ? '-30px' : '30px';
switched = !switched;
$('#switcher').animate({
'marginLeft' : "+=" + marginLeft //moves right
});
});
});
and of course you need to include jQuery.
Fiddle
I'm writing an extension that adds to an existing site so I can't modify the HTML directly. Basically there is a series of links contained in a single div separated only by spaces. I am trying to use jquery to add a link of my own at an arbitrary location in this series and open a small menu immediately next to the link, like a right click context menu. When the link/menu hover focus is gone it should disappear.
I can handle the jquery for the actual behavior but I'm a little concerned about where in the document I should be placing the html for this menu. Should it be at the end of the body? Just before/after the link? And then when I do hover over the link how do I get the correct positioning for this element? I've found examples but they all use lists. I just need a menu on link hover that appears next to the link.
In short, my main concern is about how to position the popup div correctly beside the link. Secondary to that is how to keep the menu open when I try to hover over it instead of the link.
This is how far I can get before I'm not sure what to do : http://jsfiddle.net/jRpyp/
$(".menu a").filter(function(index) { return $(this).text() === "Link 3"; }).after(" | My text | ");
$("#popup").toggle();
$("#popup-link").hover(
function(e)
{
$("#popup").show();
},
function(e)
{
$("#popup").fadeOut("slow");
});
And the HTML:
<div class="menu">
Link 1 | Link 2 | Link 3 | Link 4 <br />
More links | More links | More links | More links
</div>
<div id="popup">
<ul>
<li>Link 1</li>
<li>Link 2</li>
</ul>
</div>
First of all, #popup needs to be set to a positioning as absolute. This will enable you to position it anywhere on the page, no matter where it appears in the HTML.
This is the basic jQuery you should use 1
function (e) {
var pos = $(this).position(); // Gets the position of the link
var width = $(this).outerWidth(); // Gets the width of the link
$("#popup").css({
top: pos.top + "px", // Uses the top positioning of the link to put it in the same area
left: (pos.left + width) + "px" // First puts the menu in the same leftward position of the link, then adds the width to prevent overlap
}).show();
}
This will ensure that no matter where the link is, it will appear close to the link
If you want to add some more space between the link and the menu, simple add + and a number
For example
left: (pos.left + width + 10) + "px" // Would add 10 extra pixels, so it doesn't look like they are right next to each other
top: (pos.top + 20) + "px" // Adds 20 extra pixels
Fiddle
1: Provided by https://stackoverflow.com/a/158176/1470950
Do you want something similiar to this http://jsfiddle.net/jRpyp/4/ updated version of the script?
$("#popup").toggle();
$(".menu a").hover(function (e) {
// change selected a-tags css to get a margin
$("#popup").css({
position: "absolute",
top: 50 + "px", // based on the position of the selected a-tag
left: 100 + "px" // based on the position of the selected a-tag
}).show();
},
function (e) {
$("#popup").fadeOut("slow");
});
Regarding to one of your questions:
I can handle the jquery for the actual behavior but I'm a little
concerned about where in the document I should be placing the html for
this menu. Should it be at the end of the body? Just before/after the
link?
It doesn't matter where to place the html, since its only use is to be displayed (on a determined position) within the side. I think people often nest such html at the end of the document, within a div with an id like template (to access it easier with jQuery).
(I hope I got the question right.)
OK, I found an answer that works. I'm not sure that it's the best way to go about it so I'll go ahead and leave it open in case someone else can find something better.
First I did some more research and found the jQuery offset() function which lets me get the position of the link. From there I set the position of the div to the link. I had some issues with the hover being too picky about where the mouse was, so I created a large div that goes around the link with left padding so that the link itself wouldn't be hidden while the menu was shown and so that I could have a little bit of wiggle room outside the menu to keep it from disappearing. Changing the positioning and padding of the div will give more flexibility in how far the mouse can move before the menu fades out.
Here's the fiddle.
And here's the code minus html/css:
$(".menu a").filter(function(index) { return $(this).text() === "Link 3"; }).after(" | My text | ");
var popupPosition = $("#popup-link").offset();
// Edit positioning as needed
//popupPosition.left += $("#popup-link").width();
$("#popup").offset(popupPosition);
$("#popup").css("padding-left", $("#popup-link").width());
$("#popup").toggle();
$("#popup-link").hover(
function(e)
{
$("#popup").show();
},
function(e)
{
//$("#popup").fadeOut("slow");
});
$("#popup").hover(
function(e)
{
popupHovering = true;
$("#popup").show();
},
function(e)
{
$("#popup").fadeOut("slow");
});
I'm writing a jQuery plugin for adding context menus to elements.
Now, I need to fix the position of the context menu. If there is not enough space to show the entire context menu from the mouse bottom, then it should show from the mouse top.
I tried some things but not works like I want.
Here is the code on jsFinddle: http://jsfiddle.net/evandroprogram/pRPQq/
Thank you.
Here you go mate, I've forked and updated your fiddle here
http://jsfiddle.net/joevallender/j5Vy9/
The code change is this
var screenBottom = $(window).scrollTop() + $(window).height();
var menuHeight = _contextMenu.height();
var menuBottom = menuHeight + options.positionY;
if(menuBottom > screenBottom) {
_contextMenu.css({
top: "-=" + menuHeight
})
}
Placed just after you set _contextMenu.css()
EDIT Just tested again and that isn't pixel perfect but it does work and should give you a decent clue if you want to tweak it :)