Scroll to bottom of div when close to bottom - javascript

I am working on a chatting service and i need the site to scroll to the bottom of the chatt, and if a person whants to scroll up, the script for scrolling down will stop.
I have the chat inside a div with the id #chat_innhold, and here is my attemnt.
window.setInterval(function scrolled(o)
{
if(o.offsetHeight + o.scrollTop > o.scrollHeight - 75)
{
window.setInterval=function()
{
return false;
}
}
else
{
window.setInterval=function()
{
$("html, #chat_innhold").animate({ scrollTop: $('#chat_innhold').prop("scrollHeight")}, 'slow');
}
}
}, 1000);
When i am 75 pixels above bottom, a want to stop the scroll to bottom function.

Why are you overriding window.setInterval?

If I understood correctly, you need something like that
<div class="wrapper">
<button>Go to bottom</button>
<button class="go-top">Go to top</button>
</div>
body,
.wrapper {
margin: 0;
padding: 0;
}
.wrapper {
position: relative;
height: 1000px;
}
.go-top {
bottom: 0;
position: absolute;
left: 0;
}
var elem = $('.wrapper')[0];
if (elem.addEventListener) {
if ('onWheel' in document) {
// IE9+, FF17+, Ch31+
elem.addEventListener("wheel", onWheel);
} else if ('onmousewheel' in document) {
// old variant
elem.addEventListener("mousewheel", onWheel);
} else {
// Firefox < 17
elem.addEventListener("MozMousePixelScroll", onWheel);
}
} else { // IE8-
elem.attachEvent("onmousewheel", onWheel);
}
function onWheel(e) {
e = e || window.event;
var delta = e.deltaY || e.detail || e.wheelDelta;
if(delta < 0 || delta > 0) {
$('html, body').stop();
}
}
var deltaWindowBodyHeight = $('body').height() - $(window).height();
function goToBottom() {
$('html, body').animate({
scrollTop: deltaWindowBodyHeight - 75
}, 1000);
}
function goToTop() {
$('html, body').animate({
scrollTop: 0
}, 1000);
}
$('button').click(function() {
if($(this).hasClass('go-top')) {
goToTop();
} else {
goToBottom();
}
});
JSFiddle example

Related

Trigger function only once on scroll

I want to start a function when a div is scrolled into the viewport. My problem is, that the function is triggered/started again every time I continue to scroll.
HTML:
<div class="box"></div>
JS:
$(document).ready(function() {
function start() {
alert("hello");
}
$(window).scroll(function() {
if ( $(window).scrollTop() >= $('.box').offset().top - ($(window).height() / 2)) {
$(".box").addClass("green");
start();
} else {
$(".box").removeClass("green");
}
});
});
To sum up: the function "start" should be started, when the div is scrolled into the viewport. But it should be not triggered again, after it was triggered once.
Fiddle
You can setup a flag like:
var started = false;
function start() {
if(!started) {
alert("hello");
}
started = true;
}
$(document).ready(function() {
var started = 0;
function start() {
if(started==0) {
alert("Alert only once");
}
started = 1;
}
$(window).scroll(function() {
if ( $(window).scrollTop() >= $('.box').offset().top - ($(window).height() / 2)) {
$(".box").addClass("green");
start();
} else {
$(".box").removeClass("green");
}
});
});
*{margin:0;}
.box { background: red; height: 200px; width: 100%; margin: 800px 0 800px 0; }
.green { background: green; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<br />
<center>
<br />
<h1>scroll down</h1>
</center>
<div class="box"></div>
There's a bunch of ways to go about this. You could just remove the event listener (since you're using jQuery, I'll use the on and off methods):
$(window).on('scroll', function() {
if ( $(window).scrollTop() >= $('.box').offset().top - ($(window).height() / 2)) {
$(".box").addClass("green");
start();
} else {
$(".box").removeClass("green");
}
$(window).off('scroll');
});
if you want window scroll method to stop once the start method meet its requirement.. you can do it this way
$(document).ready(function() {
var toggleScroll = false;
function start() {
alert("hello");
}
$(window).one("scroll", checkToggleScroll);
function checkToggleScroll(){
if ( $(window).scrollTop() >= $('.box').offset().top - ($(window).height() / 2)) {
$(".box").addClass("green");
toggleScroll = true;
start();
} else {
$(".box").removeClass("green");
}
if(!toggleScroll){
$(window).one("scroll", checkToggleScroll);
}
}
});

Back to top scroll var offset for different browser widths|heights

I implemented a "back to top" or "scroll to top" button in a WordPress site which works perfectly:
jQuery(document).ready(function($) {
var offset = 500;
var speed = 10;
var duration = 250;
$(window).scroll(function() {
if ($(this).scrollTop() < offset) {
$('.topbutton').fadeOut(duration);
} else {
$('.topbutton').fadeIn(duration);
}
});
$('.topbutton').on('click', function() {
$('html, body').animate({
scrollTop: 0
}, speed);
return false;
});
});
My dilemma is that I can't find a method to change the var offset to a flexible value according to browser width|height. Thus the narrower the browser/device screen, the further down the 500px trigger point occurs, causing the "back to top" button to appear too late. Here is my CSS:
.site-footer {
background-color: #0a0a0a;
}
.topbutton {
height: 100px;
width: 100px;
position: fixed;
right: 5px;
bottom: 5px;
z-index: 1;
background-image: url("https://sheknowsphotography.co.za/wp-content/uploads/2018/12/Arrow-up-blue-ezgif.com-resize.gif");
background-repeat: no-repeat;
display: none;
}
Here is the gif image inside the footer.php, just before the </body> tag:
<?php wp_footer(); ?>
<img src="https://sheknowsphotography.co.za/wp-content/uploads/2018/12/Arrow-up-blue-ezgif.com-resize.gif">
Everything is done in child theme.
To whoever responds: thank you for your time!
The solution that works:
jQuery(document).ready(function($){
if ($(window).width() < 960) {
var offset = 500;
}
else {
var offset = 1000;
}
var speed = 10;
var duration = 250;
$(window).scroll(function(){
if ($(this).scrollTop() < offset) {
$('.topbutton') .fadeOut(duration);
} else {
$('.topbutton') .fadeIn(duration);
}
});
$('.topbutton').on('click', function(){
$('html, body').animate({scrollTop:0}, speed);
return false;
});
});

condensing code/script in head tags

I have 3 scripts hard-coded in my head tags which all target different elements in my site. However most of them are based on similar events (when mouse scrolls, etc) I am wondering if it could be combined/condensed at all. I've tried but can't seem to make it any smaller while keeping functionality.
script 1 - animates #nav away when user scrolls dwn, brings it back when scrolled up
script 2 - animates away a second menu (#nav-BN) on < 768px screens when user scrolls up or down
script 3 - hides and shows a div/button > 768px screens, hides it if smaller
<script>
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $('nav').outerHeight();
$(window).scroll(function(event) { didScroll = true; });
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 250);
function hasScrolled() {
var st = $(this).scrollTop();
if (Math.abs(lastScrollTop - st) <= delta)
return;
if (st > lastScrollTop && st > navbarHeight ) {
// Scroll Down
$('#s-nav').removeClass('nav-down').addClass('nav-up');
} else {
// Scroll Up
if (st + $(window).height() < $(document).height()) {
$('#s-nav').removeClass('nav-up').addClass('nav-down');
}
}
lastScrollTop = st;
}
</script>
<script>
var lastPos=0;
$(window).scroll(function(event) {
if (window.innerWidth < 768) {
$('#nav-BN').addClass('BN-nav-hide').removeClass('BN-nav-show');
clearTimeout($.data(this, 'scrollTimer'));
$.data(this, 'scrollTimer', setTimeout(function() {
$('#nav-BN').addClass('BN-nav-show').removeClass('BN-nav-hide');
}, 250));
}
});
</script>
<script>
$(window).scroll(function () {
if (window.innerWidth > 768) {
if ($(window).scrollTop() + $(window).height() > ($(document).height() - 200)) {
$("#up-btn").fadeIn(500);
} else {
$("#up-btn").fadeOut(500);
}
} else {
$("#up-btn").fadeOut(250);
}
});
</script>
you might notice some important things:
Replace multiple jQuery search by storing the objects in variables
Is not necessary to have two classes for hidden and shown, you can have one class named 'active' instead of BN-nav-show, and in case that class is missing it should be NB-nav-hide
if (window.innerWidth > 768) and (window.innerWidth < 768) can be merged into one unique structure:
if(){
} else {
}
This should help
<script>
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $('nav').outerHeight();
var $window = $(window);
var $upBtn = $("#up-btn")
var lastPos=0;
window.scroll(function(event) {
didScroll = true;
var $navBN = $('#nav-BN');
if (window.innerWidth > 768) {
if ($window.scrollTop() + window .height() > ($(document).height() - 200)) {
upBtn.fadeIn(500);
} else {
upBtn.fadeOut(500);
}
} else {
navBN.removeClass('active');
clearTimeout($.data(this, 'scrollTimer'));
$.data(this, 'scrollTimer', setTimeout(function() {
navBN.addClass('active');
}, 250));
upBtn.fadeOut(250);
}
});
function hasScrolled() {
var st = $(this).scrollTop();
if (Math.abs(lastScrollTop - st) <= delta) return;
if (st > lastScrollTop && st > navbarHeight ) {
// Scroll Down
$('#s-nav').removeClass('nav-down').addClass('nav-up');
} else {
// Scroll Up
if (st + $(window).height() < $(document).height()) {
$('#s-nav').removeClass('nav-up').addClass('nav-down');
}
}
lastScrollTop = st;
}
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 250);
</script>
If you don't have a problem with toggle classes, then you can do that
https://jsfiddle.net/9yhug2qg/1/
var windowST, navBar, navBarHeight;
$(window).on('scroll', function () {
windowST = $(window).scrollTop();
navBar = $('.navbar');
navBarHeight = parseInt(navBar.height());
if (windowST > navBarHeight) {
$(navBar).addClass('out-of-area');
} else {
$(navBar).removeClass("out-of-area");
}
});
* { margin: 0;padding: 0; }
body { height: 700vh; }
.navbar {
position: fixed;
width: calc(100%);
height: 70px;
background-color: #0ff;
color: #fff;
transition: all 1s ease
}
ul {
position: absolute;
top: 50%;
transform: translateY(-50%);
visibility: visible;
width:calc(100% - 60px);
height: 60px;
background-color: #fff;
}
.navbar.out-of-area {
transform: translateY(-100px);
}
.navbar > .nav_btn {
position: absolute;
width: 40px;
height: 40px;
background-color: #151515;
right: 4px;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
visibility: hidden;
}
#media only screen and (max-width: 768px) {
.navbar > .nav_btn { visibility: visible; }
ul { visibility: hidden; }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<nav class="navbar">
<nav class="nav_btn"></nav>
<ul></ul>
</nav>
</div>

Resize Header On Scrolling

I'm trying to change the header size (which I named #headwrapper) and its background color when scrolling down. As you can see I need it to trigger the class .small when scrolling is > 145.
It is working only when I minimize the screen's width to 600px or less.
I have this problem since I had to change the very last line from height: '130px' to height: 'auto'; max-height: '1000px'. This in order to fully see the drop down menu triggered when the screens width is 600px. It was cutting in half with height 130px.
This is the script:
$(window).scroll(function () {
var sc = $(window).scrollTop()
if (sc > 145) {
$("#pageheader, #headwrapper, #main-nav, .logos, #social, #main- logo").addClass("small");
}
else {
$("#pageheader, #headwrapper, #main-nav, .logos, #social, #main- logo").removeClass("small")
}
});
$(function(){
$('#headwrapper').data('size', 'big');
});
$(window).scroll(function(){
if ($(document).scrollTop() > 200) {
if ($('#headwrapper').data('size') == 'big') {
$('#headwrapper').data('size', 'small');
$('#headwrapper').stop().animate({
height:'75px'
}, 400);
}
} else {
if ($('#headwrapper').data('size') == 'small') {
$('#headwrapper').data('size', 'big');
$('#headwrapper').stop().animate({
height: 'auto';
max-height: '1000px'
}, 400);
}
}
});
You have an error in the animate object syntax. Replace the ; with , and quote them:
$('#headwrapper').stop().animate({
"height": 'auto', // Change ; to , as this is an object.
"max-height": '1000px'
}, 400);
And move everything inside the document's ready function:
$(function() {
$('#headwrapper').data('size','big');
$(window).scroll(function () {
var sc = $(window).scrollTop();
if (sc > 145) {
$("#pageheader,#headwrapper,#main-nav,.logos,#social,#main- logo").addClass("small");
}
else {
$("#pageheader,#headwrapper,#main-nav,.logos,#social,#main- logo").removeClass("small");
}
});
$(window).scroll(function() {
if($(document).scrollTop() > 200) {
if($('#headwrapper').data('size') == 'big') {
$('#headwrapper').data('size','small');
$('#headwrapper').stop().animate({
height:'75px'
},400);
}
}
else
{
if($('#headwrapper').data('size') == 'small') {
$('#headwrapper').data('size','big');
$('#headwrapper').stop().animate({
"height": 'auto',
"max-height": '1000px'
},400);
}
}
});
});

Bug with elastic scrolling and menu bar in JS

I want to set up a menu bar like you see her in JSfiddle:
http://jsfiddle.net/gvjeyywa/21/
There it works exactly the way I want it to … But on the webpage it has a bug, I think it's because of the elastic scrolling in OSX … On scrolling down the menu bar should slide in from the top to set up on top:0px, being fixed there… But if you scroll back to top and the elastic scrolling scrolls higher than the body is… the menu jumps too high…
Here see the live example:
http://www.cyrill-kuhlmann.de/index.php/projects
on iOS it's a complete mess too…
Here is the JS Code:
var bitFlag = false;
var isActive = true;
var lastScrollTop = 0;
var timeoutId;
$navigation = $("#navigation");
$(window).scroll(function (event) {
var intWindowTop = $(window).scrollTop();
var intElementBottom = $navigation.offset().top + $navigation.height();
if (intWindowTop > lastScrollTop) {
isActive = true;
if (!bitFlag) {
$navigation.css("position", "absolute").css("top", intWindowTop + "px");
bitFlag = true;
}
if (timeoutId) {
clearTimeout(timeoutId);
}
timeoutId = setTimeout(function () {
if (intWindowTop > intElementBottom) {
intDelayTime = setTimeout(function () {
if (isActive) {
$navigation.animate({ top: intWindowTop + "px" }, {
duration: 800,
step: function () {
if ($(window).scrollTop() < $navigation.offset().top) {
$(this).stop(true,true);
}
},
complete: function () {
intDelayTime2 = setTimeout(function () {
$("#navigation").css("position", "fixed").css("top", "0px");
bitFlag = false;
isActive = false;
}, 1);
}
});
}
}, 500);
}
}, 100);
} else {
$navigation.css("position", "fixed").css("top", "0px");
bitFlag = false;
isActive = false;
}
lastScrollTop = intWindowTop;
});
And this is the CSS:
#navigation {
position:absolute;
top: 0px;
left: 0px;
right: 0px;
height: 80px;
background-color: #FFF;
z-index:999;
padding-top: 25px;
padding-left: 45px;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
Does someone have an idea? Unfortunately I'am a bloody starter in JS… I am thankful for any help…
problem is this: intWindowTop > lastScrollTop.
this value is true, when you scroll into the negative area, that comes with webkit.
so you have to check, if the value is positive via intWindowTop > 0
$(window).scroll(function () {
var intWindowTop = $(window).scrollTop();
var intElementBottom = $navigation.offset().top + $navigation.height();
if ( intWindowTop > lastScrollTop && intWindowTop > 0 ) {
//...
} else {
//...
}
note that i removed the variable "event" as well. you dont use it, so why declare it..?

Categories