How to know when an element will be off screen? - javascript

I am writing a simple script that displays a dialog box when a user hovers over a profile picture. It dynamically determines the profile pics location on the page and then places itself to the left of it and about 100px above it. This part is working fine.
My issue arises when a profile pic is at the top of the screen and a user mouses over it. The dialog will appear but the top portion of it will be above the fold (i.e. not in the current browser window). Naturally this is not good usability and I would like it to appear on the screen.
My question is how do I know when a dialog will be off screen so I can recalculate its position on the page?
I saw this question which seems like the same as mine but unfortunately no actual solution was provided other then to link to a jQuery plugin. I am using Prototype.

Prototype already provides positions with Element.viewportOffset().
Edit, as Mathew points out document.viewport gives the rest of the information. For example,
var dialogtop = dialog.viewportOffset().top;
if (dialogtop < 0) {
// above top of screen
}
elseif (dialogtop + dialog.getHeight > document.viewport.getHeight()) {
// below bottom of screen
}

You'll want to find the profile pic's position relative to the document (here's a good article on how, though I suspect Prototype's Element.Offset already handles this), then compare it to the body's scrollTop property to see if it's close enough to the top that it needs to have its dialog repositioned.

I am familiar with this problem, however, last time I was able to use a library (Seadragon) to get the screen dimensions and mouse position. I was also working with a fixed size overlay so no code to share with you other than general approach.
For my pop up box I decided to use the event mouse position rather than location of the div on the page. I then compared the mouse position to the known screen size, which I determined on start or resize.
From How do I get the size of the browser window using Prototype.js?
var viewport = document.viewport.getDimensions(); // Gets the viewport as an object literal
var width = viewport.width; // Usable window width
var height = viewport.height; // Usable window height
In Prototype you can also get the mouse coordinates:
function getcords(e){
mouseX = Event.pointerX(e);
mouseY = Event.pointerY(e);
//for testing put the mouse cords in a div for testing purposes
$('debug').innerHTML = 'mouseX:' + mouseX + '-- mouseY:' + mouseY;
}
Source : http://remorse.nl/2008/06/mouse_coordinates_with_prototype/

Related

Get element position relative to screen. (Or alternative solution)

I am aware this had been asked before, but no answer actually did the trick as far as I tested them.
Basically what I need is to change some element styles as soon as it "hits" the top border of the screen while scrolling down. This element is a 'Back to Top' button that will be sitting in a section and start following the user when they scroll pass said section.
I am not asking about CSS properties, I am asking about some JS property or method that allow me to know this. IE:
$('#back').distanceFromTopOfTheScreen() // This value will decrease as I scroll down
I know there are other soultions, but the client has asked for this behavior.
Any idea?
You can :
distance = $('#eleId')[0].getBoundingClientRect().top;
For more about getBoundingClientRect() look at the MDN Documentation
Note: This value change when you're scrolling, it gives you the distance between the top border of the element and the top of the Page
Sometimes JQuery make's everything more confusing than Native Javascript, even forgothing the very basics functions:
window.onscroll = function() { fixPosition()};
function fixPosition() {
var Yplus = 4; //number of lines in every scroll
document.getElementById('element').style.top = document.body.scrollTop + Yplus ;
}
This will allows you to move an "element" static on the window following the scroll.

Calculating Height of Sidebar Dynamically

I'm trying to work out the algorithm for a fixed div that grows in height (while scrolling) until it's equal to the height of the viewport or div with fixed position relative to another div and the bottom of the viewport
I am using Twitter Bootstrap affix to lock my secondary navigation bar (yellow) and my sidebar (black) to the top of the screen when the user scrolls that far. 
This works fine. The sidebar is the piece that's giving me trouble.  When it is in its in its starting position (as shown in the diagram belorw), I want the top of the bar to sit 30px
down from the secondary navigation bar (yellow) and 30px up from the bottom of the page. 
As the user scrolls, the bar should grow in height so that it remains 30px beneath the secondary navigation bar and 30px above the bottom of the screen (As shown in the diagram below)
After the bar is fixed position, I am able to do what I need to do.  
.sidebar { 
position:fixed;
top:100px;  
bottom:30px;
left:30px;
}
What I can't figure out is how to position the TOP of the sidebar relative to my
secondary navigation bar and the BOTTOM of my sidebar relative to the bottom
of the screen. I've tried calculating the height of the sidebar at the beginning and the end of the
scroll but this causes issues.
I've also tried calculating the final height of the sidebar and letting the bottom of
the sidebar just run off the edge of the screen (when it's in its initial position), but
if there's not enough content on the right side to warrant scrolling, I have no way
of getting to the bottom items in the scroll bar.  Plus my screen starts bouncing
in a really un­attractive way.
below is the current code in use:
ShelvesSideBar.prototype._resize_sidebar = function(_this) {
var PADDING = 50;
var window_height = $(window).height(),
nav_bar_height = $('.nav_bar').height() + $('.secondary_tabs').height(),
sidebar_height = window_height - nav_bar_height - PADDING,
sidebar_scrollable_height = sidebar_height - $('.bar_top').height();
_this.$container.height(sidebar_height);
_this.$container.find('.bar_bottom').height(sidebar_scrollable_height);
/* reset the nanoscroller */
_this.$container.nanoScroller();
};
   
this code is called on page load and again on window resize. Any help would be greatly appreciated!
I've been trying to do something similar (minus the fixed elements and navbars). What I found was in order to do any sort of relative height scaling every element above the element I wished to scale all the way up to the opening html tags had to have a relative height set, even if it was just height:100%;. (here's my original question Variable height, scrollable div, contents floating)
My goal was to have the body height fixed to window size like a native full screen application would be with my content subareas scrolling, so this is a bit off topic for what you're wanting to accomplish. But I tried using JS/JQ to start off with as you're trying to do currently and found that I simply couldn't get the window height because the default behaviour for height management is to expand the page height until everything on the page fits. And all the getHeight methods I tried we're getting the page height not window/viewport height as promised. So you may wish to try fixing your body's height to the window and going from there using overflow:scroll; to scroll the page.
A quick note on overflow:scroll; if you have users who use WP8 IE (and probably other versions of IE) it may be advantageous to implement FTscroller to handle all your scroll elements as the overflow property defaults to hidden and is a fixed browser property. The only problem with FTscroller is because it uses CSS offsets to move the content container it may wreak havoc on elements that are designed to switched to fix when they reach x height from top of page because technically the top of page (or rather the top of the container they're in) isn't at the top of the page anymore it's beyond it. Just something to be aware of if you do need to cater for this browser.
And apologies for the complexity of my sentence structure. :/
so I was able to figure this out, for anyone still looking. What I ended up doing was binding to the window scroll event and - whenever the scroll occurred - I check if the class "affix" has been added to the sidebar. If it has, then I perform one set of calculations to determine sidebar height. Otherwise, I perform the other set of calculations. Code below:
/* called on window scroll */
var PADDING = 70;
var window_height = $(window).height(),
nav_bar_height = $('.nav_bar').height() + $('.secondary_tabs').height(),
header_height = $('.prof_block').height() - nav_bar_height,
sidebar_height = _this.$container.hasClass("affix") ? window_height - nav_bar_height - PADDING : window_height - (header_height + nav_bar_height) - PADDING,
sidebar_scrollable_height = sidebar_height - $('.bar_top').height();
_this.$container.height(sidebar_height);
_this.$container.find('.bar_bottom').height(sidebar_scrollable_height);

image gallery /slide with zoom

I wanted to do something similar to this.
In this case when the user click in the image, this images is showed with 100% of the browser height, and the user can go to the next/previous image. When the user clicks again the image is showed in a bigger size(may be in the real size) and the user can go up and down in the image, but with out scroll, just moving the mouse.
What I want to do is when the user click the first time in the image go right to the last step: The biggest image with up and down synchronized with the mouse movement, and the possibility to go to the next image. In other words a mix with the features of the first and the second step of the original case.
Where I can see a tutorial, or a demo?? or how can I do the this??
Thanks
Basically, there are three parts to what you want to do.
Clicking on the image will show the image with respect to browser height
You can go to the next image while you are in this mode
Click on that image again will go into a supersize mode where your mouse position dictates what part of the image you are looking at
I'm not going to write a whole fiddle to demonstrate this because it's a decent amount of work but I can tell you the basic ideas.
With #1, when you click on the image, you will create a new div with a z-index of some high number (like 9999). The position would be fixed, and you will create
$(window).resize(function() {
var windowheight = $(window).height();
$("#imgdiv").css("height", windowheight);
});
Which will resize the image if the user decides to resize your window, this way it's always taking up the full height of your browser.
With #2, the arrows just create a new img tag. And the idea is something like
function loadnew() {
// create the new image
var newimg = "<img id='newimg'></img>"
$("#imgcontainer").append(newimg);
// make sure it has the same classes as the current img
// so that it's in the same position with an higher z-index
// then load the image
$("#newimg").addClass( "class1 class2" );
$("#newimg").css( "z-index", "+=1" );
$("#newimg").css( "opacity", 0 );
$("#newimg").attr("src", "url/to/img");
// animate the thing and then replace the src of the old one with this new one
$("#newimg").animate( {
opacity: 1;
}, 1000, function() {
$(oldimg).attr("src", $("#newimg").attr("src"));
});
}
Now with #3, you will size the image with respect to the width. The div fixed positioned. So again, you need a
$(window).resize(function() {
var windowwidth= $(window).width();
$("#imgdiv").css("width", windowwidth);
});
to make sure it's always taking up the whole screen. And for the mouse movement, you need to have a mousemove event handler
$("#superimgdiv").mousemove( function(e) {
// need to tell where the mouse is with respect to the window
var height = $(window).height();
var mouseY = e.pageY;
var relativepct = mouseY/height;
// change the position relative to the mouse and the full image height
var imgheight = $("superimg").height();
$("superimgdiv").css("top", -1*relativepct*imgheight);
});
And that's it. Of course I'm leaving out a bunch of details, but this is the general idea. Hopefully this can get you started. Good luck.

Centering a Javascript pop-up window

I want to center a pop-up window within a browser. However, I'd like it to work regardless of the browser size and the browsers position within the users screen.
Position within a browser is straightforward, for example (with jQuery) :
var left = ($(window).width()/2)-(width/2);
..
uwin = window.open(...., left=...);
etc. But if the users browser is not full screen, then it positions relative to full screen rather than browser.
I can get screen using
screen.width()
but that will just position on screen so that's no better.
Anyone ?
You'll need to use both the window size and the browser position on the screen to figure out this information. You can get these from the window.screenTop and window.screenLeft properties. So, to get the the positioning you want, you would first get the position relative to the browser window:
var windowLeft = ($(window).width()/2)-(width/2);
and then you add the offset:
var screenLeft = windowLeft + window.screenLeft;
Then you can do the same for the height.

A bit of problem with implementing a modal dialog

I am developing a modal dialog as a part of a web application. There is one thing that's been of a puzzle to me. Please watch a movie clip that I just uploded at http://inter.freetzi.com/example/. I feel strongly that I have to accompany my question with a video because this is the case when it's better to see once, than to hear 100 times.
(It could be vertical scrolling, or both vertical and horizontal at the same time. But I am using horizontal scrolling in my example, so watch for it.)
Here's about my question:
Width of the transparent mask affects the width of the page itself. But in Opera, for exemple, every time the window gets resized, the page gets width that is at most close to 'true'. While in IE, once the transparent mask has affected the width, afterwards the page remembers it and stays with it. What is the problem and how to settle it? How to make IE behave the way Opera does?
In my project, I do the following:
//curViewpointW and curViewpointH are current width and height of the viewpoint (current is meant to be the moment of the resize event)
oMask.style.width = curViewpointW + 'px';
oMask.style.height = curViewpointH + 'px';
var pageWH = getPageWH(); //getPageWH() is a function that gets current width and height of the page (with scrolling if there is any)
var curPageW = pageWH[0];
var curPageH = pageWH[1];
if (curPageW > curViewpointW) {
oMask.style.width = curPageW + 'px';
}
if (curPageH > curViewpointH) {
oMask.style.height = curPageH + 'px';
}
But IE ignores that somehow...
P.S. It's jQuery in my example, so many of you may have used its dialog before.
Have you looked into setting an onresize event handler that will adjust your mask dimensions when the window is resized? If you are using Prototype, you can set up such a handler unobtrusively like this:
Event.observe(document.onresize ? document : window, "resize", function() {//dostuff});
courtesy of the Roberto Cosenza blog

Categories

Resources