Why does this code use both `document.body` and `document.documentElement`? - javascript

Okay, so I'm trying to figure out how this JS code works.. Could you explain me some things?
There's the code (I've copied some of the w3schools' code, full: https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_scroll_to_top
<button onclick="topFunction()" id="myBtn" title="Go to top">Top</button>
<script>
// When the user scrolls down 20px from the top of the document, show the button
window.onscroll = function() {scrollFunction()};
function scrollFunction() {
if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
document.getElementById("myBtn").style.display = "block";
} else {
document.getElementById("myBtn").style.display = "none";
}
}
function topFunction() {
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
}
</script>
I think that document.documentElement means it is a HTML and it contains all elements on the page. Am I wrong?
So why we need two variable setting in topFunction()? When I remove this line:
document.body.scrollTop = 0;
everything still working, so why we need this part of code? Thanks.

From the question title pre-edit:
What's the difference between document.body and document.documentElement?
document.body is the body element. document.documentElement is (in HTML documents) the html element.
So why we need two variable setting in topFunction()?
Because unfortunately, when scrolling the content of the main window, some browsers have historically scrolled html, and others body. You can try your current browser here:
var n, div;
for (n = 1; n <= 100; ++n) {
div = document.createElement('div');
div.innerHTML = String(n);
document.body.appendChild(div);
}
var bodyDisplay = document.getElementById("body-display");
var docElDisplay = document.getElementById("docel-display");
document.addEventListener("scroll", function() {
bodyDisplay.innerHTML = String(document.body.scrollTop);
docElDisplay.innerHTML = String(document.documentElement.scrollTop);
});
.top {
position: fixed;
height: 2em;
border-bottom: 1px solid #ddd;
background: white;
}
<div class="top">
<div>
body scrollTop:
<span id="body-display"></span>
</div>
<div>
documentElement scrollTop:
<span id="docel-display"></span>
</div>
</div>
<div>Scroll up and down</div>

Related

jquery else condition inside onscroll function

I have a problem in animation in onscroll event.
The if condition works very well when I scroll down and div shows without any problem, but when I scroll up, the else condition does not work, so the div doesn't hide and it is still shown.
This is the code:
$(function () {
'use strict';
var myDiv1 = $('div'),
div1Top = (myDiv1.offset().top) / 2;
$(window).on('scroll', function () {
var docScrollTop = document.documentElement.scrollTop;
if (docScrollTop >= div1Top) {
$('div').animate({opacity: '1'}, 800);
} else {
$('div').css('opacity', '0');
}
});
});
This might not be exactly what you're trying to do, but I think it's in the right ballpark:
<html>
<style>
div {
width: 500px;
height: 500px;
}
.animated_div {
background-color: green;
position: absolute;
top: 2000px;
opacity: 0;
}
.placeholder {
position: absolute;
top:4000px;
}
</style>
<body>
<div class="animated_div"></div> <!--The div that will actually be animated-->
<div class="placeholder"></div> <!--This is just something below the animated DIV, so that you can scroll below the animated DIV -->
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
'use strict';
var myDiv1 = $('.animated_div');
// Start animating the div relative to its middle
var div1Middle = myDiv1.offset().top + myDiv1.height() / 2;
// Keep track of whether the animated_div is displayed or not
var myDiv1Shown = false;
$(window).on('scroll', function () {
var docScrollTop = $(window).scrollTop(); // Top of the window in page coordinates
var docScrollBottom = docScrollTop+$(window).height(); // Bottom of the window in page coordinates
if (div1Middle > docScrollTop && div1Middle < docScrollBottom && !myDiv1Shown) {
// The div middle is within view and it's not already shown, so we need to show it
myDiv1Shown = true;
myDiv1.animate({opacity: '1'}, 800);
} else if ((div1Middle > docScrollBottom || div1Middle < docScrollTop) && myDiv1Shown) {
// The div middle is out of view and it's shown, so we need to hide it
myDiv1Shown = false;
myDiv1.animate({opacity: '0'}, 800);
}
});
});
</script>
</html>
This changes the div opacity to 1 when it's in view and changes it to 0 when it's out of view. It's considered in-view if its vertical middle is in view.
If what you want to do is essentially fade-in the div when the user scrolls it into view and then fade-out the div when the user scrolls it out of view, you might consider this as an alternative:
<html>
<style>
div {
width: 500px;
height: 500px;
}
.animated_div {
background-color: green;
position: absolute;
top: 2000px;
opacity: 0;
}
.placeholder {
position: absolute;
top:4000px;
}
</style>
<body>
<div class="animated_div"></div> <!--The div that will actually be animated-->
<div class="placeholder"></div> <!--This is just something below the animated DIV, so that you can scroll below the animated DIV -->
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
'use strict';
var myDiv1 = $('.animated_div');
var div1Top = myDiv1.offset().top;
var div1Height = myDiv1.height();
var div1Bottom = div1Top + div1Height;
$(window).on('scroll', function () {
var docScrollTop = $(window).scrollTop(); // Top of the window in page coordinates
var docScrollBottom = docScrollTop+$(window).height(); // Bottom of the window in page coordinates
// Calculate fraction of div on page
var topOffPage = Math.max(0, docScrollTop - div1Top);
var bottomOffPage = Math.max(0, div1Bottom - docScrollBottom);
var fractionOnPage = Math.max(0, div1Height - topOffPage - bottomOffPage)/div1Height;
myDiv1.css('opacity', fractionOnPage);
});
});
</script>
</html>
The snippet immediately above sets the opacity of the div to be the fraction of it that is in view (considering only the vertical dimension). So if the entire DIV is on-screen, it's fully opaque. If only half of it is onscreen (with half of it either above the scroll top or below the scroll bottom), then the opacity is 0.5, and so on. If the div is large relative to the screen, then this could cause problems. For instance, if you have a 1000px div, and people are viewing the page with a viewport of height 500px, then the div will only ever be 50% opaque at most. But you can adapt it as necessary to fit your circumstances.

javascript not rendering styles

I dont know why this code is not working!
html, css, javascript is not working in same html page
plz help I cant figure out this.. is it problem on browser or my code is wrong
every thing seems to be fine...
function render() {
var winW = window.innerWidth;
var winH = window.innerHeight;
alert('hello');
var overlay = document.getElementsByClassName('overlay');
var alert = document.getElementsByClassName('alertbox');
overlay.style.display = 'block';
overlay.style.background = 'blue';
overlay.style.height = winH + 'px';
overlay.style.width = winW + 'px';
overlay.style.border = '10px solid black';
}
.overlay{
display: none;
opacity: 0.8;
position: fixed;
background: #ccc;
z-index: 10;
width: 100%;
height:100%;
}
.alertbox{
display: none;
position: fixed;
background: magenta;
z-index: 10;
border-radius: 8px;
width: 500px;
}
<html>
<head>
<title></title>
</head>
<body>
<h3>Custom Alert Box Demo</h3>
<button type="button" onclick="alert('hello world')">render overlay</button>
<button type="button" onclick="render()">render overlay</button>
<div class="overlay"></div>
<div class="alertbox">
<div class="head"></div>
<div class="body"></div>
<div class="foot"></div>
</div>
</body>
</html>
See this fiddle
Your script has two errors. Please replace your script with the below given one
function render() {
var winW = window.innerWidth;
var winH = window.innerHeight;
var overlay = document.getElementsByClassName('overlay')[0];
var alert = document.getElementsByClassName('alertbox')[0];
overlay.style.display = 'block';
overlay.style.background = 'blue';
overlay.style.height = winH + 'px';
overlay.style.width = winW + 'px';
overlay.style.border = '10px solid black';
}
First error was in the line,
alert('hello');
because, you have a variable with name alert in your script and thus you will get an error alert is not a function in your console. If you want the alert to be shown, then you should rename your variable with name alert to some other name, may be for eg, rename it to alert1. Please see the fiddle.
Second error was in the line
var overlay = document.getElementsByClassName('overlay');
because document.getElementsByClassName() always returns an array.
According to the docs
getElementsByClassName() Returns an array-like object of all child elements which have all of
the given class names. When called on the document object, the
complete document is searched, including the root node. You may also
call getElementsByClassName() on any element; it will return only
elements which are descendants of the specified root element with the
given class names.
What I have done in the fiddle is that, I've selected the first element with the class name overlay using the index position 0. Similarly for the class alertbox.

Show/hide a div 500 px from top and 500 px before bottom

I have a page where I want an image to appear after scrolling say 500px and I used the "If you want to show a div after scrolling a number of pixels, WITHOUT jquery" code snippet from apaul34208 (show div after 800px scroll). My adapted code is like this:
<!DOCTYPE html>
<html>
<body>
<div id="myID" class="pointer hide">
<img src="image.png">
</div>
<script>
myID = document.getElementById("myID");
var myScrollFunc = function () {
var y = window.scrollY;
if (y >= 400) {
myID.className = "pointer show"
} else {
myID.className = "pointer hide"
}
};
window.addEventListener("scroll", myScrollFunc);
</script>
</body>
</html>
and CSS:
.hide {
display: none;
}
.show {
display: block;
margin-top: -80px;
}
Only problem is that I would also like it to DISAPPEAR again lets say 400 px from the bottom of the page. the page-height differs from page to page so I cant just set a range like underneath from say 400-1000 px.
<script>
myID = document.getElementById("myID");
var myScrollFunc = function () {
var y = window.scrollY;
if (y >= 400 & y <= 1000 ) {
myID.className = "pointer show"
} else {
myID.className = "pointer hide"
}
};
window.addEventListener("scroll", myScrollFunc);
</script>
</body>
</html>
Anyone have any idea how I can make this happen?
Thanks guys!
$(document).ready(function() {
$(window).scroll(function() {
console.log('scrolling ', $(window).scrollTop(), $(document).height());
if ($(window).scrollTop() >= 400 && $(window).scrollTop() <= ($(document).height() - 600)) {
$('#myID').removeClass('hide');
}
else {
$('#myID').addClass('hide');
}
});
});
.hide {
display: none;
}
.body {
height: 2000px;
}
#myID {
background-color: lightgray;
position: fixed;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="body">
<div id="myID" class="pointer hide">
STUFF HERE
</div>
</div>
use document.height to get the height of the document and rest the desired value:
myID = document.getElementById("myID");
var myScrollFunc = function () {
var y = window.scrollY;
if (y >= 400 & y <= document.height - 400) {
myID.className = "pointer show";
} else {
myID.className = "pointer hide";
}
};
window.addEventListener("scroll", myScrollFunc);

Scroll the page vertically and scroll big image inside div horizontally on mouse drag with jQuery

I have page that I want to scroll vertically on event mouse down, and I already have found the answer on this question link. In my case i have a div that contain image that user put on it and sometimes it have bigger size than my div size, with overflow:auto; i get horizontal scroll inside that div. So i need to apply drag scroll horizontally on that div.
HTML
<html>
<body>
<div id="container">
<div class="detail-title"> TITLE </div>
<div class="detail-content">
<img src="...." />
!-- long content --!
</div>
</div>
</body>
</html>
CSS
.detail-main-content-box {
background: none;
display: block;
left: 0;
min-height: 350px;
overflow: auto;
padding: 5px 5px 5px 5px;
width: auto;
}
jQuery from answer link
$(document).on({
'mousemove': function (e) {
clicked && updateScrollPos(e);
},
'mousedown': function (e) {
clicked = true;
clickY = e.pageY;
$('html').addClass('block-selection').css({ 'cursor': 'url(../img/closedhand.cur), default' });
},
'mouseup': function () {
clicked = false;
$('html').removeClass('block-selection').css('cursor', 'auto');
}
});
var updateScrollPos = function(e) {
$(window).scrollTop($(window).scrollTop() + (clickY - e.pageY));
};
how can i apply this on div? i have try to change $(document) to $('.detail-content') also change function scrollTop to scrollLeft but nothing happen. Here is the fiddle for current condition.
this has been left here unanswered for two long years, not even a useful comment. OK, here is my try. hope it can help ( le roi est mort vive le roi)
<script type="text/javascript">
var clicked = true;
var clickY = e.pageY;
$('.detail-content').on({
'mousemove': function (e) {
clicked && updateScrollPos(this,e);
},
'mousedown': function (e) {
clicked = true;
clickY = e.pageY;
$('html').addClass('block-selection').css({ 'cursor': 'grabbing' });
},
'mouseup': function () {
clicked = false;
$('html').removeClass('block-selection').css('cursor', 'auto');
}
});
var updateScrollPos = function(obj,e) {
$(obj).scrollTop($(obj).scrollTop() + (clickY - e.pageY));
clickY = e.pageY;
};
</script>

jQuery function that returns when a div touches another div upon scroll

how can I give an alert when one div hovers over another div upon scroll? here is a working example,
http://jsfiddle.net/uprosoft/Ek5Gy/267/
I cant find a jQuery code to go after though in-order to give an alert.
Code:
HTML
<div id="container">
<div id="div1">test</div>
<br>
<div id="div2"> another test</div>
</div>
CSS
#div1{
background: green;
position: fixed;
width: 100%;
}
#div2{
background: yellow;
position: relative;
width: 100%;
margin-top: 100px;
}
#container{
height: 1000px;
}
JQUERY ???
/* what jquery code goes here? to alert when the yellow div touches the green div upon scroll? */
Something like that should work:
$(window).scroll(function() {
var div1 = $("#div1");
var div2 = $("#div2");
var div1_top = div1.offset().top;
var div2_top = div2.offset().top;
var div1_bottom = div1_top + div1.height();
var div2_bottom = div2_top + div2.height();
if (div1_bottom >= div2_top && div1_top < div2_bottom) {
// overlapped
}
});​
DEMO: http://jsfiddle.net/Ek5Gy/280/
I know the question is for Jquery but either way, the same done with vanilla JS
function didDiv1TouchedDiv2() {
var div1 = document.getElementById("div1");
var div2 = document.getElementById("div2");
// Guard
if (div1 === undefined || div2 === undefined) return;
var div1Rect = div1.getBoundingClientRect();
var div2Rect = div2.getBoundingClientRect();
// We need to add the offsetHeight in order to include padding and border of element and get excact position
return div1Rect.top >= div2Rect.top + div2.offsetHeight;
}
window.addEventListener("scroll", didDiv1TouchedDiv2);

Categories