Yeah, that had crossed my mind. I was more concerned that a user might not see notifications, but I agree with you.
I do have a solution for determining if the div is in the viewport. Someone on stackoverflow had already solved this problem, but I had to change it a bit due to a Chrome bug. It's explained in documentation in the .js file below -- compare it with the version on stackoverflow to see what I changed -- the link is also in the documentation.
I tested this code in Firefox 13 and Chrome 19 on Fedora 14 and Windows XP, and in IE 8 on XP, and it worked. I'd like to ask people reading this thread to test this on different browsers and browser versions and list their configuration, but I don't anticipate there being problems.
If enough people report back that it worked for them as well, I'll merge it into my JComments fork to test it. I'm holding off on doing that because testing will require me to create a second Joomla installation on my domain. Or, smart, if you have a test environment ready to go, you could save me the trouble -- all you'd need to do is include the .js file and wrap my window.location.href setting in a check for !isVisible().
You can remove VisibilityMonitor() -- JComments won't have a use for it. I just kept it in there because it was in the original code.
visibility.html<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script type="text/javascript" src="visibility.js"></script>
<script type="text/javascript">
function msgInView()
{
window.alert( "element is in view" );
}
function msgNotInView()
{
window.alert( "element is not in view" );
}
/*
* JComments should do this
*/
function checkVisibility()
{
isVisible(document.getElementById("importantdiv")) ? msgInView() : msgNotInView();
}
/*
* JComments should not do this
*/
function startVisibilityMonitor()
{
VisibilityMonitor( document.getElementById('importantdiv'), msgInView, msgNotInView );
}
</script>
</head>
<body>
<button type="button" onclick="checkVisibility();" style="position:fixed;left:150px;top:20px;">check visibility</button>
<div id="importantdiv" style="position:absolute;top:1000px;border:1px solid #000000">hello</div>
<!-- puts 'importantdiv' somewhere in the middle of the page, instead of the bottom -->
<div style="position:absolute;top:2000px;">_</div>
</body>
</html>
visibility.js/*
* This library was written by bobince and has been modified by Kurtis LoVerde.
*
* Bobince
* Profile: http://stackoverflow.com/users/18936/bobince
* Code obtained from: http://stackoverflow.com/questions/2158991/fire-javascript-event-when-a-div-is-in-view
*
* Kurtis LoVerde
* Homepage: http://www.loverde.org
*
*
* Changes by Kurtis:
*
* 1. Chrome has a bug which puts scrollTop/scrollLeft in the wrong object when
* operating in standards mode, breaking logic bobince used to determine
* where to pull the values from. As of the date this comment was written,
* the Chrome bug was marked "won't fix" without explanation:
*
* http://code.google.com/p/chromium/issues/detail?id=2891
*
* I changed bobince's logic to look at document.documentElement *and*
* document.body, favoring document.documentElement. Standards/quirks mode
* detection has been removed.
*
* 2. Added isVisible(element) to perform one-off visibility checks.
*/
/*
* Perform a one-time check of an item's visibility.
* Returns true if the element is in view, false if not.
*/
function isVisible(element)
{
return rectsIntersect( getPageRect(), getElementRect(element) );
}
/*
* Assign a VisibilityMonitor to an element. The monitor will check
* the element's visibility after every scroll or resize event and will
* execute a function whenever the element enters or leaves view.
*/
function VisibilityMonitor(element, showfn, hidefn)
{
var isshown= false;
function check()
{
if (rectsIntersect(getPageRect(), getElementRect(element)) !== isshown)
{
isshown= !isshown;
isshown? showfn() : hidefn();
}
};
window.onscroll=window.onresize= check;
check();
}
function getPageRect()
{
var x= document.documentElement.scrollLeft || document.body.scrollLeft;
var y= document.documentElement.scrollTop || document.body.scrollTop;
var w= 'innerWidth' in window? window.innerWidth : (document.documentElement.clientWidth || document.body.clientWidth);
var h= 'innerHeight' in window? window.innerHeight : (document.documentElement.clientHeight || document.body.clientHeight);
return [x, y, x+w, y+h];
}
function getElementRect(element)
{
var x= 0, y= 0;
var w= element.offsetWidth, h= element.offsetHeight;
while (element.offsetParent!==null)
{
x+= element.offsetLeft;
y+= element.offsetTop;
element= element.offsetParent;
}
return [x, y, x+w, y+h];
}
function rectsIntersect(a, b)
{
return a[0]<b[2] && a[2]>b[0] && a[1]<b[3] && a[3]>b[1];
}