With help from various websites, I've created a very simple pop-up box using javascript that contains my contact information. I'm happy with how it works, except that the popup window that appears is positioned absolutely, and I want to have it appear relative to the browser window (ie I want the pop up to appear in the centre of the browser window, regardless of where you are on the page when you click the info icon).
I'm comfortable with HTML, but not with javascript. I know that relative positioning works very differently in javascript, but I cannot get my head around how to fix this. Any advice would be appreciated.
The webpage is here: http://www.thirstlabmedia.com/
The script is as follows:
<script type="text/javascript">
function toggle( div_id ) {
var el = document.getElementById( div_id );
if( el.style.display == 'none' ) {
el.style.display = 'block';
}
else {
el.style.display = 'none';
}
}
function blanket_size( popUpDivVar ) {
if( typeof window.innerWidth != 'undefined' ) {
viewportheight = window.innerHeight;
}
else {
viewportheight = document.documentElement.clientHeight;
}
if( ( viewportheight > document.body.parentNode.scrollHeight ) && ( viewportheight > document.body.parentNode.clientHeight ) ) {
blanket_height = viewportheight;
}
else {
if( document.body.parentNode.clientHeight > document.body.parentNode.scrollHeight ) {
blanket_height = document.body.parentNode.clientHeight;
}
else {
blanket_height = document.body.parentNode.scrollHeight;
}
}
var blanket = document.getElementById( 'blanket' );
blanket.style.height = blanket_height + 'px';
var popUpDiv = document.getElementById( popUpDivVar );
popUpDiv_height = window.innerHeight / 2 - 200;
popUpDiv.style.top = popUpDiv_height + 'px';
}
function window_pos( popUpDivVar ) {
if( typeof window.innerWidth != 'undefined' ) {
viewportwidth = window.innerHeight;
}
else {
viewportwidth = document.documentElement.clientHeight;
}
if( ( viewportwidth > document.body.parentNode.scrollWidth ) && ( viewportwidth > document.body.parentNode.clientWidth ) ) {
window_width = viewportwidth;
}
else {
if( document.body.parentNode.clientWidth > document.body.parentNode.scrollWidth ) {
window_width = document.body.parentNode.clientWidth;
}
else {
window_width = document.body.parentNode.scrollWidth;
}
}
var popUpDiv = document.getElementById( popUpDivVar );
window_width = window_width / 2 - 200;
popUpDiv.style.left = window_width + 'px';
}
function popup( windowname ) {
blanket_size( windowname );
window_pos( windowname );
toggle( 'blanket' );
toggle( windowname );
}
</script>
(My apologies for placing it all on one line; the website is created through Cargo Collective, and it doesn't accept script unless it's all placed on one line).
Use CSS position : fixed:
#my-element {
position : fixed;
top : 50%;
left : 50%;
margin : -100px 0 0 -250px;
width : 500px;
height : 200px;
z-index : 1000;
}
Here is a demo: http://jsfiddle.net/huRcV/1/
This centers a 500x200px element in the viewport. The negative margins are used to center the element with respect to its dimensions. If the user scrolls the page, the element will stay centered in the viewport.
Docs for position: https://developer.mozilla.org/en/CSS/position
fixed
Do not leave space for the element. Instead, position it at a
specified position relative to the screen's viewport and doesn't move
when scrolled. When printing, position it at that fixed position on
every page.
You can do this with JavaScript but it's probably better to use the CSS version. If you do want to use jQuery here is a quick example:
var $myElement = $('#my-element');
$(window).on('scroll resize', function () {
$myElement.css({
top : ($(this).scrollTop() + ($(this).height() / 2)),
});
});
Here is a demo: http://jsfiddle.net/huRcV/ (notice that position : fixed is changed to position : absolute for this demo)
Related
I am using JavaScript to detect when an element is visible on scroll like this..
function isOnScreen(elem) {
// if the element doesn't exist, abort
if( elem.length == 0 ) {
return;
}
var $window = jQuery(window)
var viewport_top = $window.scrollTop()
var viewport_height = $window.height()
var viewport_bottom = viewport_top + viewport_height
var $elem = jQuery(elem)
var top = $elem.offset().top
var height = $elem.height()
var bottom = top + height
return (top >= viewport_top && top < viewport_bottom) ||
(bottom > viewport_top && bottom <= viewport_bottom) ||
(height > viewport_height && top <= viewport_top && bottom >= viewport_bottom)
}
jQuery( document ).ready( function() {
window.addEventListener('scroll', function(e) {
if( isOnScreen( jQuery( '.shipping-logos' ) ) ) { /* Pass element id/class you want to check */
alert( 'The specified container is in view.' );
}
});
});
This is working well, but I am trying to change things so that the detection only happens if the screen is scrolling up? When a user is scrolling down I want the function to ignore the element.
Anyone have an example of how to achieve this?
I've created the following functionality where an image is fixed on the left while scrolling the content and the quote appears for a few pixels.
It's working all right, the only problem is that I'd like to add this many times on the same page and, as it is, it just works with the first image.
The second one is not fixed while scrolling and the quote maintains hidden...
How can I make run this function for every image?
This is a working example
HTML:
<section id="cont_quote" class="maxwidth">
<article class="cont_q hasImage">
<p>Content</p>
<img class="alignleft img_quote" src="/large.jpg" alt="" width="433" height="553" />
<blockquote>
<h3>Why this training plan works</h3>
</blockquote>
<p>Content</p>
</article>
</section>
JS:
// Stick image on scroll
$(window).on('load resize', function () {
if ($(window).width() >= 769) {
var $element = $('#cont_quote');
var $follow = $element.find('.img_quote');
var followHeight = $element.find('.img_quote').outerHeight();
var height = $element.outerHeight() - 300;
var window_height = $(window).height();
$(window).scroll(function () {
var pos = $(window).scrollTop();
var top = $element.offset().top;
// Check if element is above or totally below viewport
if (top + height - followHeight < pos || top > pos + window_height) {
return;
}
var offset = parseInt($(window).scrollTop() - top);
if (offset > 0) {
$follow.css('transform', 'translateY('+ offset +'px)');
}
})
}
});
// Quote show on viewport
function inViewport( element, viewport = { top: 0, bottom: innerHeight } ){
// Get the elements position relative to the viewport
var bb = element.getBoundingClientRect();
// Check if the element is outside the viewport
// Then invert the returned value because you want to know the opposite
return !(bb.top > viewport.bottom || bb.bottom < viewport.top);
}
var myViewport = { top: innerHeight * .5, bottom: innerHeight * .6 };
var myElement = document.querySelector( '#cont_quote blockquote' );
// Listen for the scroll event
document.addEventListener( 'scroll', event => {
// Check the viewport status
if( $(window).width() >= 600 ){
if( inViewport( myElement, myViewport ) && $('.cont_q').hasClass('hasImage') ) {
if( $(window).width() >= 769 ){
myElement.style.opacity = 1;
myElement.style.left = '-25%';
} else {
myElement.style.opacity = 1;
myElement.style.left = '-5%';
}
} else if( inViewport( myElement, myViewport )) {
if( $(window).width() >= 769 ){
myElement.style.opacity = 1;
myElement.style.left = '-15%';
} else {
myElement.style.opacity = 1;
myElement.style.left = '13%';
}
} else {
myElement.style.opacity = 0;
myElement.style.left = '-40%';
}
} else {
myElement.style.opacity = 1;
myElement.style.left = '5%';
}
});
First of all, I'm not a javascript expert. I'm going crazy on trying to figure out how to make a conditional execution of a certain javascript. I'm using JQuery to absolutely center my block in a browser page, but only if the screen size is bigger than 480px (In other meaning, I don't want this script to run on smartphones). I'm using CSS media query to indicate my request. The thing is, this script works fine on all smartphones, Safari 5+, IE10, Firefox 13. BUT IT DOESN'T WORK ON IE6-9 and Opera 12 (As far as I understand, they don't support transitions). CAN ANYONE PLEASE HELP ME FIGURE OUT WHAT I AM DOING WRONG? And if there's a better way of doing this? (I tried #media query in CSS but The script keeps on running no matter what)... I would really appreciate the help.
<script>
if (matchMedia('only screen and (max-device-width:800px) and ' + '(orientation: portrait)').matches) {
// smartphone/iphone... maybe run some small-screen related dom scripting?
event.preventDefault();
} else{
//Absolute Content Center
function CenterItem(theItem){
var winWidth=$(window).width();
var winHeight=$(window).height();
var windowCenter=winWidth/2;
var itemCenter=$(theItem).width()/2;
var theCenter=windowCenter-itemCenter;
var windowMiddle=winHeight/2;
var itemMiddle=$(theItem).height()/2;
var theMiddle=windowMiddle-itemMiddle;
if(winWidth>$(theItem).width()){ //horizontal
$(theItem).css('left',theCenter);
} else {
$(theItem).css('left','0');
}
if(winHeight>$(theItem).height()){ //vertical
$(theItem).css('top',theMiddle);
} else {
$(theItem).css('top','0');
}
}
$(document).ready(function() {
CenterItem('.content');
});
$(window).resize(function() {
CenterItem('.content');
});
} //end of "else" (normal execution)
</script>
You can try this :-
<script>
var screenWidth = screen.width;
if (screenWidth > 480 ) {
//Absolute Content Center
function CenterItem(theItem){
var winWidth=$(window).width();
var winHeight=$(window).height();
var windowCenter=winWidth/2;
var itemCenter=$(theItem).width()/2;
var theCenter=windowCenter-itemCenter;
var windowMiddle=winHeight/2;
var itemMiddle=$(theItem).height()/2;
var theMiddle=windowMiddle-itemMiddle;
if(winWidth>$(theItem).width()){ //horizontal
$(theItem).css('left',theCenter);
} else {
$(theItem).css('left','0');
}
if(winHeight>$(theItem).height()){ //vertical
$(theItem).css('top',theMiddle);
} else {
$(theItem).css('top','0');
}
}
$(document).ready(function() {
CenterItem('.content');
});
$(window).resize(function() {
CenterItem('.content');
});
}
</script>
To get exact Height and Width in all browser is quite big deal because of IE, But no worries is the solution for all Browser including IE 6 to latest.
Here are those 2 function:
if (matchMedia('only screen and (max-device-width:800px) and ' + '(orientation: portrait)').matches) {
// smartphone/iphone... maybe run some small-screen related dom scripting?
event.preventDefault();
} else{
//Absolute Content Center
$(document).ready(function() {
CenterItem('.content');
});
$(window).resize(function() {
CenterItem('.content');
});
} //end of "else" (normal execution)
function CenterItem(theItem){
var winWidth=getWindowWidth();
var winHeight=getWindowHeight();
var windowCenter=winWidth/2;
var itemCenter=$(theItem).width()/2;
var theCenter=windowCenter-itemCenter;
var windowMiddle=winHeight/2;
var itemMiddle=$(theItem).height()/2;
var theMiddle=windowMiddle-itemMiddle;
if(winWidth>$(theItem).width()){ //horizontal
$(theItem).css('left',theCenter);
} else {
$(theItem).css('left','0');
}
if(winHeight>$(theItem).height()){ //vertical
$(theItem).css('top',theMiddle);
} else {
$(theItem).css('top','0');
}
}
function getWindowHeight() {
var myHeight = 0;
if( typeof( window.innerWidth ) == 'number' ) {
myHeight = window.innerHeight;
} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
myHeight = document.documentElement.clientHeight;
} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
myHeight = document.body.clientHeight;
}
return myHeight;
}
function getWindowWidth() {
var myWidth = 0;
if( typeof( window.innerWidth ) == 'number' ) {
myWidth = window.innerWidth;
} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
myWidth = document.documentElement.clientWidth;
} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
myWidth = document.body.clientWidth;
}
return myWidth;
}
This will help you to get exact height in any Browser, in that way you can apply your logic. Hope this help!!!
Simplest thing is not to attach the event handler if the media query does not match.
$.fn.extend({
centerItem: function () {
return this.each(function () {
var $this = $(this),
hCenter = ( $(window).width() - $this.width() ) / 2,
vCenter = ( $(window).height() - $this.height() ) / 2;
$this.css({
left: hCenter > 0 ? hCenter : 0,
top: vCenter > 0 ? vCenter : 0
});
});
}
});
$(function() {
var bigScreen = 'only screen and (max-device-width:800px) and (orientation: portrait)';
if ( matchMedia(bigScreen).matches ) {
$(window).resize(function() {
$('.content').centerItem();
});
}
});
Notes
$() replaces $(document).ready(). See http://api.jquery.com/ready/
By convention, only object constructors start with a capital letter, so your CenterItem() function should actually be called centerItem().
I've turned your function into a jQuery plugin. You can of course continue using your own implementation if you find that confusing.
The .css() function can take an object argument so you can set multiple CSS properties in one step.
I've used the ternary operator (expression ? ifTrue : ifFalse) to replace the if.
You can do
window.innerHeight
window.innerWidth
to get the dimensions of the viewport. Now you could do:
var width = window.innerWidth
if (width > 480){
/* do desktop stuff*/
}
As alternative, you could go for the UserAgentString and/or Operating with:
window.navigator
(more reliable Detect-script)
However, either attempt might fail in some cirumstances.
edit: would be nice if you posted your match-media function.
edit2: use the script for correct viewport detection: https://stackoverflow.com/a/2035211/1047823
and then alter your code:
if ( getViewport()[0] < 480 ) {
// smartphone/iphone... maybe run some small-screen related dom scripting?
event.preventDefault();
} else{
// your desktop code
}
I have written a scrollSpy function that detects user activity as they scroll up and down on a webpage.
<script type="text/javascript">
function yPos() {
var pos = 0;
if( typeof( window.pageYOffset ) == 'number' ){
//Netscape compliant
pos = window.pageYOffset;
} else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
//DOM compliant
pos = document.body.scrollTop;
} else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
//IE6 standards compliant mode
pos = document.documentElement.scrollTop;
}
return pos;
}
window.onscroll = function(){
var scrollPos = yPos(), goTopElem = document.getElementById('scroll'), docBody = document.getElementsByTagName('body')[0];
if(goTopElem && scrollPos < 500 ) // user has scrolled up
goTopElem.parentNode.removeChild(goTopElem); // remove go to top link
else if(scrollPos > 500 && !goTopElem){
var newDiv = document.createElement('DIV'), newLink = document.createElement('A'), txt = document.createTextNode('[back to top]');
newLink.setAttribute('href','javascript:scroll(0,0);');
newLink.appendChild(txt);
newDiv.setAttribute('id','scroll');
newDiv.appendChild(newLink);
docBody.appendChild(newDiv);
}
}
</script>
<style type="text/css">
#scroll {
position:fixed;
right: 0px;
bottom: 0px;
display: block;
}
</style>
The problem is with internet explorer, when scrolling down a link should appear at the bottom right corner of your window - but this does not happen.
Please help.
If you are talking IE6 or an older IE7 then position: fixed is not supported. If not, please update question with more specifics about which version of IE you are talking about.
In a web application, I have a page that contains a DIV that has an auto-width depending on the width of the browser window.
I need an auto-height for the object. The DIV starts about 300px from the top screen, and its height should make it stretch to the bottom of the browser screen. I have a max height for the container DIV, so there would have to be minimum-height for the div. I believe I can just restrict that in CSS, and use Javascript to handle the resizing of the DIV.
My javascript isn't nearly as good as it should be. Is there an easy script I could write that would do this for me?
Edit:
The DIV houses a control that does it's own overflow handling (implements its own scroll bar).
Try this simple, specific function:
function resizeElementHeight(element) {
var height = 0;
var body = window.document.body;
if (window.innerHeight) {
height = window.innerHeight;
} else if (body.parentElement.clientHeight) {
height = body.parentElement.clientHeight;
} else if (body && body.clientHeight) {
height = body.clientHeight;
}
element.style.height = ((height - element.offsetTop) + "px");
}
It does not depend on the current distance from the top of the body being specified (in case your 300px changes).
EDIT: By the way, you would want to call this on that div every time the user changed the browser's size, so you would need to wire up the event handler for that, of course.
What should happen in the case of overflow? If you want it to just get to the bottom of the window, use absolute positioning:
div {
position: absolute;
top: 300px;
bottom: 0px;
left: 30px;
right: 30px;
}
This will put the DIV 30px in from each side, 300px from the top of the screen, and flush with the bottom. Add an overflow:auto; to handle cases where the content is larger than the div.
Edit: #Whoever marked this down, an explanation would be nice... Is something wrong with the answer?
document.getElementById('myDiv').style.height = 500;
This is the very basic JS code required to adjust the height of your object dynamically. I just did this very thing where I had some auto height property, but when I add some content via XMLHttpRequest I needed to resize my parent div and this offsetheight property did the trick in IE6/7 and FF3
If I understand what you're asking, this should do the trick:
// the more standards compliant browsers (mozilla/netscape/opera/IE7) use
// window.innerWidth and window.innerHeight
var windowHeight;
if (typeof window.innerWidth != 'undefined')
{
windowHeight = window.innerHeight;
}
// IE6 in standards compliant mode (i.e. with a valid doctype as the first
// line in the document)
else if (typeof document.documentElement != 'undefined'
&& typeof document.documentElement.clientWidth != 'undefined'
&& document.documentElement.clientWidth != 0)
{
windowHeight = document.documentElement.clientHeight;
}
// older versions of IE
else
{
windowHeight = document.getElementsByTagName('body')[0].clientHeight;
}
document.getElementById("yourDiv").height = windowHeight - 300 + "px";
With minor corrections:
function rearrange()
{
var windowHeight;
if (typeof window.innerWidth != 'undefined')
{
windowHeight = window.innerHeight;
}
// IE6 in standards compliant mode (i.e. with a valid doctype as the first
// line in the document)
else if (typeof document.documentElement != 'undefined'
&& typeof document.documentElement.clientWidth != 'undefined'
&& document.documentElement.clientWidth != 0)
{
windowHeight = document.documentElement.clientHeight;
}
// older versions of IE
else
{
windowHeight = document.getElementsByTagName('body')[0].clientHeight;
}
document.getElementById("foobar").style.height = (windowHeight - document.getElementById("foobar").offsetTop - 6)+ "px";
}
Simplest I could come up...
function resizeResizeableHeight() {
$('.resizableHeight').each( function() {
$(this).outerHeight( $(this).parent().height() - ( $(this).offset().top - ( $(this).parent().offset().top + parseInt( $(this).parent().css('padding-top') ) ) ) )
});
}
Now all you have to do is add the resizableHeight class to everything you want to autosize (to it's parent).
inspired by #jason-bunting, same thing for either height or width:
function resizeElementDimension(element, doHeight) {
dim = (doHeight ? 'Height' : 'Width')
ref = (doHeight ? 'Top' : 'Left')
var x = 0;
var body = window.document.body;
if(window['inner' + dim])
x = window['inner' + dim]
else if (body.parentElement['client' + dim])
x = body.parentElement['client' + dim]
else if (body && body['client' + dim])
x = body['client' + dim]
element.style[dim.toLowerCase()] = ((x - element['offset' + ref]) + "px");
}