As you can see the image below, there is "A", "B", "C", "D" and "E" on the website, and the user may only can see the A, B, and a little parts of D in their browser. They need to require to scroll down the browser or some users may have a bigger screen, or a longer window on their browser that allow they can even see the element C.
Ok, my question is, is this possible to let me know what the user seeing on their browser using javascript? In this element, is "A", "B" and "D".
Using the following, you can get the browser's viewport size.
window.innerHeight;
window.innerWidth;
Refer to: http://www.javascripter.net/faq/browserw.htm
If you want to detect how far they have scrolled down the page, you can use
window.scrollX; // Horizontal scrolling
window.scrollY; // Vertical scrolling
Also, I have found a window object - window.screen. On my system it has the following data:
window.screen.availHeight = 994;
window.screen.availLeft = 0;
window.screen.availTop = 0;
window.screen.availWidth = 1280;
window.screen.colorDepth = 32;
window.screen.height = 1280;
window.screen.pixelDepth = 32;
window.screen.width = 1280;
Try it :) http://jsfiddle.net/Aj2fU/5/
$('input').click(function(){
// check for visible divs with class 'check'
$('.check').each(function(){
var pos = $(this).offset(),
wX = $(window).scrollLeft(), wY = $(window).scrollTop(),
wH = $(window).height(), wW = $(window).width(),
oH = $(this).outerHeight(), oW = $(this).outerWidth();
// check the edges
// left, top and right, bottom are in the viewport
if (pos.left >= wX && pos.top >= wY &&
oW + pos.left <= wX + wW && oH + pos.top <= wY + wH )
alert('Div #' + $(this).attr('id') + ' is fully visible');
else // partially visible
if (((pos.left <= wX && pos.left + oW > wX) ||
(pos.left >= wX && pos.left <= wX + wW)) &&
((pos.top <= wY && pos.top + oH > wY) ||
(pos.top >= wY && pos.top <= wY + wH)))
alert('Div #' + $(this).attr('id') + ' is partially visible');
else // not visible
alert('Div #' + $(this).attr('id') + ' is not visible');
});
});
Updated to work with very wide divs. Basically it checks whether the left, top and right, bottom edges of the divs are both in the visible part of the screen, partially or outside of the viewport.
Basically, you'd first have to measure the viewport dimentions, by using the window object, then you'd need to loop through each of the elements that you want to check, and calculate wether they fit.
See this jsfiddle for an example.
Here's the code (for posterity's sake):
HTML:
<div id="info">
<p class="wxh"></p>
<p class="txl"></p>
<p class="report"></p>
</div>
<h1>A big list!</h1>
<ul></ul>
CSS:
#info{
position: fixed;
right: 0px;
text-align: center;
background: white;
border: 2px solid black;
padding: 10px;
}
JS:
$(function(){
$(window).bind('scroll.measure resize.measure',function(){
// Gather together the window width, height, and scroll position.
var winWidth = $(window).width(),
winHeight = $(window).height(),
winLeft = $(window).scrollLeft(),
winTop = $(window).scrollTop(),
winBottom = winTop + winHeight,
winRight = winLeft + winWidth,
inView = [];
// Loop over each of the elements you want to check
$('.inview').each(function(){
// Get the elements position and dimentions.
var pos = $(this).position(),
width = $(this).outerWidth(),
height = $(this).outerHeight();
// Set bottom and right dimentions.
pos.bottom = pos.top + height;
pos.right = pos.left + width;
// Check whether this element is partially within
// the window's visible area.
if((
pos.left >= winLeft &&
pos.top >= winTop &&
pos.right <= winRight &&
pos.bottom <= winBottom
) || (
pos.left >= winLeft && pos.top >= winTop &&
pos.left <= winRight && pos.top <= winBottom
) || (
pos.right <= winRight && pos.bottom <= winBottom &&
pos.right >= winLeft && pos.bottom >= winTop
)){
// Change this to push the actual element if you need it.
inView.push( $(this).text() );
}
});
// For the purposes of this example, we only need the
// first and last element, but in your application you may need all.
var first = inView.shift(),
last = inView.pop();
// Show the details in the info box.
$('#info .wxh').text( winWidth+' x '+winHeight );
$('#info .txl').text( winTop+' x '+winLeft );
$('#info .report').text( 'Showing from '+first+' to '+last );
});
// The rest is just setup stuff, to make the area scrollable.
for( var i=0; i<100; i++ ){
$('ul').append('<li class="inview">List item '+i+'</li>');
}
$(window).trigger('resize.measure');
})
You can get window's visible area by,
var pwidth = $(window).width();
var pheight = $(window).height();
Then get document scroll,
$(document).scroll(function(e) {
var top = $(this).scrollTop();
$("h1").html("total visible area is from:"+ top +" to "+ (pheight + top) +"px");
});
Full example is here : http://jsfiddle.net/parag1111/kSaNp/
Related
I am struggleing in issue. The issue that i am trying to popup context menu but when i click at the edges of the container div. the context menu getting flow out from this container div.
Example :
This is the menu when i click somewhere away from the edges.
This what happen if i click near to the edges.
HTML:-
<div id="rows-menu-wrapper-container" class="rows-menu-wrapper-container" style="/*display: none;*/" onclick="$(this).remove()">
<div id="rows-menu-wrapper" class="rows-menu-wrapper">
<div id="rows-menu-wrapper-menu-item" class="rows-menu-wrapper-menu-item"><label class="form-label text-truncate rows-menu-wrapper-menu-item-label">Open Menu</label></div>
</div>
</div>
CSS:-
.rows-menu-wrapper-container {
width: 100vw;
height: 100vh;
position: fixed;
top: 0px;
left: 0px;
pointer-events: auto;
background-color: rgba(26,26,26,0.11);
}
Placing the menu using JS:-
// top position
var topY = e.target.getBoundingClientRect().top + document.documentElement.scrollTop
var topX = e.target.getBoundingClientRect().left + document.documentElement.scrollLeft - 250
newPaper.find(".rows-menu-wrapper").css('top' , topY + 'px' )
newPaper.find(".rows-menu-wrapper").css('left' , topX + 'px' )
$('body').append(newPaper)
var paperHeight = newPaper.css('height').replace('px' , '') - 400
var delta = (e.clientY - newPaper.css('height').replace('px' , ''))
delta = parseFloat(delta.toString().replace('-' , '') )
delta = delta * 1.5
if ( paperHeight <= e.clientY ){newPaper.find(".rows-menu-wrapper").css('top' , topY - delta + 'px' )}
I Checked many guides but never understand how it is work.
I would be greatful if someone make it simple for me :(
UPDATE1
I managet to get around of this with below:
// top position
var topY = e.target.getBoundingClientRect().top + document.documentElement.scrollTop
var topX = e.target.getBoundingClientRect().left + document.documentElement.scrollLeft - 250
newPaper.find(".rows-menu-wrapper").css('left' , topX + 'px' )
newPaper.find(".rows-menu-wrapper").css('top' , topY + 'px' )
$('body').append(newPaper)
var totalHeight = newPaper.css('height').replace('px' , '')
var clickY = e.clientY
var elementHight = newPaper.find(".rows-menu-wrapper").css('height').replace('px' , '')
var delta = totalHeight - clickY - elementHight
if (delta <= 0){topY = topY - elementHight + 20 }
newPaper.find(".rows-menu-wrapper").css('top' , topY + 'px' )
IDK if this approach is ok or not clean.
How can i detect if some element is visible? For better understading look at the image below.
I want to fire event when the image is half-visible. It would be great if it would work for all browsers and devices (tablets and smartphones).
Jquery.fracs plugin seems to do exactly what you need.
function callback(fracs: Fractions, previousFracs: Fractions) {
if(fracs > 0.5)
doSomething();
};
var fracs = $("img").fracs(callback);
Your Window is between
$(document).scrollTop()
and
$(document).scrollTop() + $(window).height()
If the
$(element).offset().top
falls between those, it should be visible.
EDIT: I am assuming your element (whose visibility is to be determined) is absolutely positioned. If not, it would be a bit more complicated.
EDIT2: This is only to determine visibility in case of vertical offset. For the horizontal version, replace "scrollTop" with "scrollLeft", "height" with "width" and "top" with "left".
There's a neat plugin, jQuery fracs written specifically for this purpose.
You want to check whether the item is viewable from the bottom of the screen or the top. so the logic would be this:
on window scroll event
if item.y is less than scroll.y, calculate amount off screen
if item.y + item.height is greater than scroll.y + scroll.height, calculate amount off screen
deduct both values off the item.height to find the total off screen
create a percentage of this
So in javascript this would work something like this:
var el = document.getElementById('item1'),
rect = el.getBoundingClientRect(),
item = {
el: el,
x: rect.left,
y: rect.top,
w: el.offsetWidth,
h: el.offsetHeight
};
window.addEventListener('scroll', function (e) {
var deduct = 0,
percentage = 0,
x = window.pageXOffset,
y = window.pageYOffset,
w = window.innerWidth,
h = window.innerHeight;
if (item.y < y) {
deduct += (y - item.y);
}
if ((item.y + item.h) > (y + h)) {
deduct += (item.y + item.h) - (y + h);
}
if (deduct > item.h) {
deduct = item.h;
}
percentage = Math.round(((item.h - deduct) / item.h) * 100);
});
I've excluded the support for older browsers, but if you need it it would be:
x = (window.pageXOffset !== undefined) ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft,
y = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop,
w = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
h = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
var $w = $(window), wh = $w.height(),
top = $w.scrollTop(), bottom = top + wh,
$img = $("#image"),
imgCenter = $img.offset().top + $img.height()/2;
if (imgCenter >= top && imgCenter < bottom) {
// the image is half-visible
}
How do I find out the absolute position of an element on the current visible screen (viewport) using jQuery?
I am having position:relative, so offset() will only give the offset within the parent.
I have hierarchical divs, so $("#me").parent().offset() + $("#me").offset() doesn't help either.
I need the position in the window, not the document, so when the document is scrolled, the value should change.
I know I could add up all the parent offsets, but I want a cleaner solution.
var top = $("#map").offset().top +
$("#map").parent().offset().top +
$("#map").parent().parent().offset().top +
$("#map").parent().parent().parent().offset().top;
Any ideas?
Update:
I need to get the exact gap in pixels between the top of my div and the top of the document, including padding/margins/offset?
My code:
HTML
<div id="map_frame" class="frame" hidden="hidden">
<div id="map_wrapper">
<div id="map"></div>
</div>
</div>
CSS
#map_frame{
border:1px solid #800008;
}
#map_wrapper {
position:relative;
left:2%;
top:1%;
width:95%;
max-height:80%;
display:block;
}
#map {
position:relative;
height:100%;
width:100%;
display:block;
border:3px solid #fff;
}
jQuery to resize the map to fill the screen*
var t = $("#map").offset().top +
$("#map").parent().offset().top +
$("#map").parent().parent().offset().top +
$("#map").parent().parent().parent().offset().top;
$("#map").height($(window).height() - t - ($(window).height() * 8 / 100));
Thanks...
See .offset() here in the jQuery doc. It gives the position relative to the document, not to the parent. You perhaps have .offset() and .position() confused. If you want the position in the window instead of the position in the document, you can subtract off the .scrollTop() and .scrollLeft() values to account for the scrolled position.
Here's an excerpt from the doc:
The .offset() method allows us to retrieve the current position of an
element relative to the document. Contrast this with .position(),
which retrieves the current position relative to the offset parent.
When positioning a new element on top of an existing one for global
manipulation (in particular, for implementing drag-and-drop),
.offset() is the more useful.
To combine these:
var offset = $("selector").offset();
var posY = offset.top - $(window).scrollTop();
var posX = offset.left - $(window).scrollLeft();
You can try it here (scroll to see the numbers change): http://jsfiddle.net/jfriend00/hxRPQ/
For the absolute coordinates of any jquery element I wrote this function, it probably doesnt work for all css position types but maybe its a good start for someone ..
function AbsoluteCoordinates($element) {
var sTop = $(window).scrollTop();
var sLeft = $(window).scrollLeft();
var w = $element.width();
var h = $element.height();
var offset = $element.offset();
var $p = $element;
while(typeof $p == 'object') {
var pOffset = $p.parent().offset();
if(typeof pOffset == 'undefined') break;
offset.left = offset.left + (pOffset.left);
offset.top = offset.top + (pOffset.top);
$p = $p.parent();
}
var pos = {
left: offset.left + sLeft,
right: offset.left + w + sLeft,
top: offset.top + sTop,
bottom: offset.top + h + sTop,
}
pos.tl = { x: pos.left, y: pos.top };
pos.tr = { x: pos.right, y: pos.top };
pos.bl = { x: pos.left, y: pos.bottom };
pos.br = { x: pos.right, y: pos.bottom };
//console.log( 'left: ' + pos.left + ' - right: ' + pos.right +' - top: ' + pos.top +' - bottom: ' + pos.bottom );
return pos;
}
BTW, if anyone want to get coordinates of element on screen without jQuery, please try this:
function getOffsetTop (el) {
if (el.offsetParent) return el.offsetTop + getOffsetTop(el.offsetParent)
return el.offsetTop || 0
}
function getOffsetLeft (el) {
if (el.offsetParent) return el.offsetLeft + getOffsetLeft(el.offsetParent)
return el.offsetleft || 0
}
function coordinates(el) {
var y1 = getOffsetTop(el) - window.scrollY;
var x1 = getOffsetLeft(el) - window.scrollX;
var y2 = y1 + el.offsetHeight;
var x2 = x1 + el.offsetWidth;
return {
x1: x1, x2: x2, y1: y1, y2: y2
}
}
Just as a preface to make sure I am clear, I don't want the div to appear dead centre in the middle of the page, I want it in the middle of the viewable window. So if you imagine a long page and the user has scrolled down to near the bottom and clicks the button the div will appear in the centre of the screen near the bottom of the page.
here is my code, which doesn't work in chrome:
function centerdiv() {
var scrolledX, scrolledY;
scrolledX = document.body.scrollLeft;
scrolledY = document.body.scrolltop;
var centerX, centerY;
centerX = document.body.clientWidth;
centerY = document.body.clientHeight;
var leftoffset = scrolledX + (centerX - 100) / 2;
var topoffset = scrolledY + (centerY - 100) / 2;
$('.current div[name="popup"]').css({'top' : topoffset + 'px', 'left':
leftoffset + 'px'});}
$(function() {
$("html").ajaxStart(function() {
centerdiv();
$(".current div[name=popup]").show();
});
$("html").ajaxComplete(function() {
$(".current div[name=popup]").hide();
});
});
Note, this is for an iphone mobile website and the ajaxstart function attaching to the html is crucial as it doesn't work on the iphone any other way on my website.
You forget to set position to absolute, or fixed
$('.current div[name="popup"]').css({'top' : topoffset + 'px', 'left':
leftoffset + 'px', 'position':'absolute' });}
Here is my solution that works fine:
var winH = $(window).height();
var winW = $(window).width();
$(this).css('top', winH/2 - $(this).height()/2);
$(this).css('left', winW/2 - $(this).width()/2);
$(this).show();
$(this) must refer to the DIV element you want to show in the center.
wh = $(window).height();
dh = $("#div").height();
$("#div").css("top",(wh - dh)/ 2 + $(window).scrollTop() + 'px');
Edit:
Not the same for width, it's actually:
ww = $(width).width();
dw = $("#div").width();
$("#div").css("left",(ww - dw)/ 2 + 'px');
But it really depends if you have a fixed viewport or not, there are many ways to center it...
Good Luck!
If you don't have horizontal scrolling you can do it partially with straight CSS
div{
left: 50%;
margin-left: -[box_width / 2]px;
}
I had a problem where I am position a popup <div> in the center of the window using:
var popup = $("#popup"), popupWidth = popup.css("width").replace("px",""), popupHeight = popup.css("height").replace("px","");
var xPosition = ($(window).width() - popupWidth) / 2;
var yPosition = (($(window).height() - popupHeight) / 2) + $(window).scrollTop();
if (yPosition <= 0){
yPosition = '0';
} else if(yPosition <= $(window).scrollTop()){
yPosition = $(window).scrollTop();
} else {
yPosition = yPosition - 68; //minus top shaddow height
}
if (xPosition >= $('body').offset().left) {
xPosition = xPosition;
} else {
xPosition = '0';
}
$(popup).css({
'top': yPosition + 'px',
'left': xPosition + 'px',
'display' : 'block',
'height' : 'auto'
}).addClass("popup-open");
The problem I had was that on first load the height of the popup was being returned as 0 because it is hidden until after the position above has been worked out. To resolve this I set a default height via CSS and then once the popup has been displayed I overwrite this to auto.
The problem now is that if the popup has been closed and re-opened the height is auto. Is there a way to find the CSS height:value in the stylesheet not the inline height:auto
Updated Code
Following Nicola answer here is the fixed code:
var popup = $("#popup"), popupWidth = popup.css("width").replace("px",""), popupHeight = popup.css("height").replace("px","");
// Save/Get original height
if(popupHeight == "auto"){
popupHeight = popup.data('origHeight');
} else {
popup.data('origHeight', popupHeight);
}
var xPosition = ($(window).width() - popupWidth) / 2;
var yPosition = (($(window).height() - popupHeight) / 2) + $(window).scrollTop();
Why don't you save the original values in a variable?
var popup = $("#popup"), popupWidth = popup.css("width").replace("px",""), popupHeight = popup.css("height").replace("px","");
var originalHeight = popupHeight;
var originalWidth = popupWidth;
When you reopen the pop up you use the original values instead of the actual values
Or you could use use data() to store it and retrieve it
$('#popup').data('origHeight', popupHeight);
//the use $('#popup').data('origHeight') to retrieve it