Positioning bug when initialising animated div - javascript

I am creating a horizontal menu bar with a series of links. Underneath the current page link, there is an absolutely positioned div with a fixed size and a black background. When any of the other links are hovered over, this "selection indicator" slides across to underneath the hovered link. I have managed to create this effect as desired.
However, I am having an issue with the position of the "selector" div when the page first loads. For some reason the div sets it's initial position to exactly 5 pixels left of where it is supposed to be (underneath the current page link). I am using the same code to initialise the div as I am for the animation itself, and the bug only appears when the page is loaded. As soon as a link is hovered over, the "selector" slides into the correct positions until the page is refreshed/reloaded.
A working example of the menu (and the bug) can be found at www.jamiedavies.me
Here is the html structure of my navigation bar:
<header>
<h1>Main Title</h1>
<nav id="mainNav">
<ul>
<li>Link1</li>
<li>Link2</li>
<li>Link3</li>
<li>Link4</li>
</ul>
</nav>
<div id="pageSelector"></div>
</header>
Here is the related CSS:
nav#mainNav {
position: absolute;
right: 0px;
top: 63px;
}
nav#mainNav ul li {
display: inline;
list-style-type: none;
margin-left: 35px;
}
div#pageSelector {
height: 5px;
left: -999px;
position: absolute;
top: 91px;
visibility: hidden;
width: 25px;
}
And here is the javascript/jquery code that is responsible for animating the selector:
$( document ).ready( function() {
var offset = $( "header" ).offset().left;
$( "#pageSelector" ).css( "visibility", "visible" );
$( "#mainNav li" ).find( "a" ).each( function( i ) {
$( this ).mouseover( function( e ) {
var l = $( this ).offset().left - offset;
var w = $( this ).width();
$( "#pageSelector" ).animate( {
left: l,
width: w
}, 175, "swing" );
} );
} );
$( "#mainNav" ).mouseleave( function( e ) {
$( "#pageSelector" ).animate( {
left: $( "#mainNav li a.current" ).offset().left - offset,
width: $( "#mainNav li a.current" ).width()
}, 175, "swing" );
} );
$( "#mainNav" ).mouseleave();
} );

Try using
$(window).bind("load", function() {
instead of
$( document ).ready( function() {
Because, it seems the animation script completed execution before the other elements are supposedly loaded first, such as your special fonts and graphics, which most probably caused a mathematical error in alignment computation.
Hope this solves your problem.

Related

how to open a new page from link in a box instead of new tab or new window in HTML5?

I was searching for a tutorial or code that will help to show data with image in a box "instead of new window" or "instead of same window" .
Hyper link will open the page in a box or frame but parent html will be remain in background, when the box will be closed the parent window of HTML will be shown again instead of reloading.
I do not know what is called this process and I have searched for tutorials but failed to find as I wanted.
I want to do something like this link http://photoswipe.com/ shows when image is clicked.
I am new and help please.
Thank you.
It's called a modal or overlay. When used for images it's often called a lightbox.
Here is a rough demo using jQuery. Basically you have an element that contains thumbnails of your images. Those elements have a data- attribute that points to a larger sized image. When the user clicks a thumbnail you use JavaScript to read the value of the data- attribute, create an image element and insert it into the modal/overlay. The modal/overlay will be a positioned element using fixed or absolute positioning. When the user closes the modal the container element for the image is emptied so you do not have two images in the modal the next time an image is clicked and the modal/overlay is opened.
var $overlay = $( '.photo-box-overlay' );
var $overlayIMG = $( '.photo-box-img' );
$( '.photo-box' ).on( 'click', 'img', function ( e ) {
var $target = $( e.target );
var $img = $( '<img/>', {
src: $target.attr( 'data-large' )
} );
$overlayIMG.append( $img );
$overlay.css( 'display', 'block' );
} );
$( '.photo-box-close' ).on( 'click', function ( e ) {
$overlay.css( 'display', 'none' );
$overlayIMG.empty();
} );
.photo-box-overlay {
display: none;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
height: 100%;
padding: 2rem;
background-color: rgba( 0, 0, 0, 0.8 );
}
.photo-box-close {
position: absolute;
top: 10px;
right: 10px;
height: 30px;
width: 30px;
font-size: 30px;
line-height: 30px;
color: #f1f1f1;
cursor: pointer;
}
.photo-box-overlay img {
max-width: 100%;
display: block;
height: auto;
position: absolute;
left: 50%;
top: 50%;
transform: translate( -50%, -50% );
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="photo-box">
<img src="https://unsplash.it/300/150?image=85" data-large="https://unsplash.it/900/450?image=85">
<img src="https://unsplash.it/300/150?image=100" data-large="https://unsplash.it/900/450?image=100">
<img src="https://unsplash.it/300/150?image=125" data-large="https://unsplash.it/900/450?image=125">
</div>
<div class="photo-box-overlay">
<div class="photo-box-close">×</div>
<div class="photo-box-img"></div>
</div>
This is a quick demo aimed at illustrating what is required to create the functionality you're looking for. It most likely is not production ready and can/should be improved upon.
I'm changing my answer sorry. As you want to dynamicly show the picture, you are goin to create data- attr to element that includes links and then do jquery do put them into the box as you suggesting. Here is the link of DEMO

Simple image with text slider/rotator

I need to create a simple image + text rotator. Like on the picture https://dl-web.dropbox.com/get/Public/rotator.jpg?_subject_uid=6084477&w=AADd9lfxtZZzhWbGMTKwMdWn3eVjgGZ_OplgxVycsivbHA.
It will be a small block in the body of the page. Elements should change automatically after certain time, but it should be also possible to rotate them with arrows.
I am a newbie in programming, so my apologies if this is too obvious question. I suppose I should use CSS and Javascript here?
Also I've tried to google for some code example, but everything I find looks too complicated, while I need really light and basic functionality.
Thanks for advice.
The basic idea of something like this is to have a div with position: relative and width and height of one image. Lets call it #images_holder. In this #images_holder would be another div with position: absolute, height of one image, and width of all images. Lets call this inner div #moving_part. In this #moving_part you can put your images. If you want to have images with text, create div with float: left, position: relative and width and height of one image for each image. Lets call this divs .image_holder. Inside .image_holder you can put your images and texts for example as spans with position: absolute.
With something like this you are able to move the #moving_part by setting left with javascript.
I wrote an example of this using jQuery, but it's intended just to show you the way, it's not complete solution. It has some flaws, like if you click multiple times on move_left_button while moving, it can move your images outside viewable area, as the checking if it can be moved is done as soon as you click the button and it does not consider if it is already moving. To solve this you should use for example data-moving attribute, set it to true when moving is started and to false when it's finished, and start moving only if it is set to false. It would be also good idea if the width and height were dynamicly obtained from elements instead of hardcoding it. With this code as it is you will have to put your own values for widths and heights, and calculate when moving should be allowed based on image width, count of images and current left value.
Also this would work only if you have just one slider per page. If you want to have more you have to change ids to classes, and rewrite the code so it move only moving_part of the images_holder you clicked. Something like $( ".images_holder" ).each( function(){ $this_moving_part = $( this ).find( ".moving_part" ); /* and so on... */ } );
Here is Jsfiddle: http://jsfiddle.net/5Lc7cc7u/
HTML:
<div id="images_holder">
<div id="move_left_button">LEFT</div>
<div id="move_right_button">RIGTH</div>
<div id="moving_part" data-direction="to_left">
<div class="image_holder">
<span>image 1</span>
<img src="http://i.ytimg.com/vi/Bor5lkRyeGo/hqdefault.jpg">
</div>
<div class="image_holder">
<span>image 2</span>
<img src="http://i.ytimg.com/vi/Bor5lkRyeGo/hqdefault.jpg">
</div>
<div class="image_holder">
<span>image 3</span>
<img src="http://i.ytimg.com/vi/Bor5lkRyeGo/hqdefault.jpg">
</div>
</div>
</div>
CSS:
#images_holder {
position: relative;
overflow: hidden;
width: 480px;
height: 360px;
color: red;
}
#moving_part {
position: absolute;
top: 0;
width: 1440px; /* image_width * number_of_images */
height: 360px;
left: 0;
}
.image_holder {
float: left;
width: 480px;
height: 360px;
position: relative;
}
.image_holder span {
position: absolute;
top: 20px;
left: 200px;
}
#move_left_button {
position: absolute;
top: 0;
left: 0;
z-index: 999;
}
#move_right_button {
position: absolute;
top: 0;
right: 0;
z-index: 999;
}
Javascript:
$( "#move_left_button" ).click( function() {
move_left();
} );
$( "#move_right_button" ).click( function() {
move_right();
} );
function move_left() {
if( get_acct_left() >= -480 ) {
$( "#moving_part" ).animate( {
left: "-=480px"
}, 1000, function() {
if( get_acct_left() <= -480 * 2 ) {
$( "#moving_part" ).attr( "data-direction", "to_right" );
}
} );
}
}
function move_right() {
if( get_acct_left() < 0 ) {
$( "#moving_part" ).animate( {
left: "+=480px"
}, 1000, function() {
if( get_acct_left() >= 0 ) {
$( "#moving_part" ).attr( "data-direction", "to_left" );
}
} );
}
}
function get_acct_left() {
return parseInt( $( "#moving_part" ).css( "left" ) );
}
function move_to_next() {
if( $( "#moving_part" ).attr( "data-direction" ) === "to_left" ) {
move_left();
} else {
move_right();
}
}
setInterval( move_to_next, 4000 );

How to move/position DIV container by changing CSS values using Javascript?

I got two div containers as blocks with some fixed width and maybe height and display: block;
<div class="one"></div>
<div class="two"></div>
When you hover your mouse over container .one I need somehow to apply margin-top (or padding-top) to container .two so it moves couple pixels below while mouse is over .one and when you move mouse pointer aside, .two comes back to it's original position.
.one:hover + .two
{
margin-top: 2px;
}
second div must be followed by first div
.one:hover ~ .two
{
margin-top: 2px;
}
If some other element present between one and two, try this.
For your javascript (jQuery) solution:
$( ".one" ).hover(
function() {
$('.two').css('marginTop', '5px');
}, function() {
$('.two').css('marginTop', '0');
});
For smoother movement:
$( ".one" ).hover(
function() {
$('.two').animate({
marginTop: "5px"
}, 500 );
}, function() {
$('.two').animate({
marginTop: "0"
}, 500 );
});
Added a Demo

jQuery accordion "heightStyle: fill" with display set to none on page load

My World
jQuery 1.9.1
jQuery UI 1.10.3, although my jsfiddle example uses UI 1.9.2 and seems to work fine.
My Problem
There are many similar questions to this on stackoverflow, but I was unable to find a suitable answer. Basically I've got a jQuery accordion that is not to be displayed when the page loads, and its display can be changed to block via the jQuery .toggle() method. The toggle works fine, but the heightStyle: "fill" does not fill the space appropriately unless the parent div is displayed when the page is loaded, which I don't want.
My Attempts at Solutions
Repositioning the script at the end of the document and in the <head> section.
Rearranging the order in which the toggle happens: there is a second element, #map, which is toggled off at the same time as the accordion is toggled on, and vice versa.
As I am not entirely sure whether the accordion needs a parent container in the first place, I've tried it several ways: toggling the #accordion div, its parent div, and both div's.
For good measure, I've also attempted the .accordion( "refresh" ) method, as well as having a resizable container, on both the parent div and the #accordion. No soup.
Various CSS positioning for the parent container and #accordion.
Getting my hands dirty deep within jQuery.js. Given my fledgling experience with javascript, THAT didn't last long. Seriously, had to look up this thing ===. :)
My, THIS is Interesting
When the toggle button is clicked to hide the accordion and show #map again, you can see the heightStyle: "fill" actually work for a second! I slowed the transition duration in the jsfiddle so that it can be seen more easily.
SO, whatever is enabling the correct height calculation for heightStyle: "fill", that is what I need to have happen all the time. Any suggestions appreciated!
js fiddle: http://jsfiddle.net/Y8B4W/1/
HTML
<div>
<div class="page-header">
<div id="menu">Menu</div>
</div>
<div id="leftpanel">
<div id="accordion">
<h3>Heading 1</h3>
<div>
<p>...</p>
</div>
<!-- ...repeat for three more headings/sections... -->
</div><!--accordion-->
</div><!-- #leftpanel -->
<div id="map"></div>
</div>
CSS
body {
padding: 0;
margin: 0;
width: 100%;
height: 100%;
color: #000;
}
.page-header {
width: 100%;
height: 3em;
background: gray;
}
#menu {
font-size: 1em;
margin: 0.5em;
font-weight: bold;
cursor: pointer;
}
#leftpanel {
display: none;
background: blue;
padding: 0;
margin: 0;
position: absolute;
top: 3em;
left: 0;
bottom: 0;
width: 100%;
}
#map {
position: absolute;
bottom: 0;
top: 3em;
width: 100%;
background: yellow;
line-height: 1.5em;
}
Javascript
$( "#accordion" ).accordion({
heightStyle: "fill",
collapsible: true
});
$( "#menu" ).click(function() {
$( "#map" ).toggle({
duration: 2000
});
$( "#leftpanel" ).toggle({
duration: 2000
});
$( "#accordion" ).accordion( "refresh" );
});
This is kind of a cheap and cheeky hack, but it works. Basically the height of the parent div, #leftpanel, was not being calculated correctly when the page loaded (which is when jQuery assigns the accordion's height) because of its display:none property. SO, I just grabbed the height myself and assigned it to #accordion manually before the accordion functionality is even added, which works like a dream:
$( "#menu" ).click(function() {
$( "#map" ).toggle( "slow" );
if ($( "#leftpanel" ).css("display") == "none") {
$(function() {
$( "#leftpanel").css("display", "block");
var accordHt = $( "#leftpanel" ).css( "height" );
$( "#accordion").css("height", accordHt);
$( "#accordion" ).accordion({
heightStyle: "fill",
collapsible: true
});
});
};
});
And if you're wondering why the 'if' statement instead of just assigning the property outright, it's because of a media query in which I have #leftpanel being displayed when the page loads on screen widths 800px and up.
Go ahead, fiddle: http://jsfiddle.net/72rw2/
Another way is to call a refresh after display:none changes.
$( "#menu" ).click(function() {
$( "#leftpanel").css("display", "block");
$( "#accordion" ).accordion( "refresh" );
}

Containment option for a draggable

I specify the containment option for a draggable to be 'document' but the draggable element cannot be dragged outside of the container. This is only possible if I specify a very high z-index. This results in a strange display (draggable floats over other page elements). What must I specify to have the draggable divs from the editdiv container be draggable to the editdiv2 container?
$(function() {
$( "#editdiv" ).resizable();
$( "#editdiv" ).draggable();
$( "#editdiv" ).draggable("option", "handle", '#heading');
$( "#editdiv2" ).resizable();
$( "#editdiv2" ).draggable();
$( "#editdiv2" ).draggable("option", "handle", '#heading');
$( ".comurl" ).draggable();
$( ".comurl" ).draggable("option", "handle", '#dhandle');
$( "div.droppable" ).droppable({
drop: function( event, ui ) {
var $item = ui.draggable;
$item.fadeOut(function() {
$item.css( {"left":"", "top":"", "bottom":"", "right":"" }).fadeIn();
});
$item.appendTo( this );
}
});
$( ".comurl" ).draggable({ containment: 'document' });
});
If I change the containment to 'parent' or 'window' the draggable divs in the container seem to be more constrained than if I select 'document'.
Since I thought that z-index was an issue, I set the z-index for the ui-draggable-dragging class in the css.
.ui-draggable-dragging {
z-index: 999999;
background-color: red;
}
What must I fix to be able to drag an element div, e.g. Facebook.com from the first container to the second? I have a jsfiddle at http://jsfiddle.net/gkvgn/8/. Thanks.
Had to remove overflow: hidden;
.link_drop_box{
height:80%;
/* overflow:hidden; */
}
.comdiv {
position:absolute;
padding: 0;
border: 1px solid DarkKhaki;
border-radius: 3px 3px 0px 0px;
box-shadow: inset 0px 0px 10px DarkKhaki;
/* overflow-y: hidden;
overflow-x: hidden; */
}
http://jsfiddle.net/gkvgn/10/ .

Categories