Scroll down to bottom when new message is sent - javascript

I have a comment box and I am using following JS to set scroll to bottom and for it scroll down when new message is posted.
window.setInterval(function() {
var elem = document.getElementById('Commentbox');
elem.scrollTop = elem.scrollHeight;
}, 500);
It kind of works, when a new message is posted it scrolls down, but when I scroll up to look at old messages it scrolls me back down. Is there a way to prevent from that from happening?

I wouldn't use an interval function to scroll down, cause you scroll every 500 millis with your implementation. I think you have a function, that adds new messages and is called on incoming messages:
function addMessage() {
// here you add the new message to DOM
// ...
// then you can scroll down once to show the new messages
var elem = document.getElementById('Commentbox');
elem.scrollTop = elem.scrollHeight;
}
If you post the code how you add your new messages, i can help you better.

Because the correct solution was not working for me, I did something like this:
$('.your-div-class').scrollTop($('.your-div-class').height()*$('.your-div-class').height());
How I came up with the idea?
First I found the height of the div I want to auto-scroll by writing in the console of the browser:
console.log($('.your-div-class').height());.
Then I found the scrollTop value:
console.log($('.your-div-class').scrollTop());.
Then I put this in the console:
$('.your-div-class').scrollTop($('.your-div-class').height()*$('.your-div-class').height());,
and found out that it only takes me half way down and realized,
$('.your-div-class').scrollTop($('.your-div-class').height()*$('.your-div-class').height());
would take me scrolled enough downwards.
If it doesn't work for you. You can use:
$('.your-div-class').scrollTop($('.your-div-class').height()*1000);.
This should work for you just fine.

Set the interval as a variable and then clear the interval when the scrolling down is completed, using window.clearInterval().
var timer = window.setInterval(function() {
var elem = document.getElementById('Commentbox');
elem.scrollTop = elem.scrollHeight;
window.clearInterval(timer);
}, 500);

#Wowsk has a good answer, but your follow up question sounds like you are looking for a slight difference in functionality. I think this should get you there, but I've not tested it yet.
var lastScrollTop = 0;
var elem = document.getElementById('Commentbox');
var timer = window.setInterval(function() {
elem.scrollTop = elem.scrollHeight;
lastScrollTop = elem.scrollTop
}, 500);
elem.addEventListener("scroll", function(){
if(lastScrollTop < elem.scrollTop){
window.clearInterval(timer);
}
}, false);
I just went ahead and tested it before posting, hope it helps - refer to the fiddle: https://jsfiddle.net/condorhauck/ak1L12pd/1/

Related

click event - how to make click event revert back to original gradually

So I have worked hard to get this code correct thus far. Basically my click event makes my shapes DECAY gradually start being affected. It works perfectly as I wanted. But my question is when I let go of holding down my mouse or finger it automatically jumps back to the original frame. Can I please get some help on how to make it gradually go back (or gradually end) like how it starts? that way its a fluid animation from start to finish.
Here's my Click event code
decaybackup = config.shader.decay;
world.resize()
});
let interval='';
let myshape = document.getElementById('shapeId');
myshape.addEventListener('pointerdown', function(event) {
interval = setInterval(()=>{
config.shader.decay += .001;
},1)
});
myshape.addEventListener('pointerup', function(event) {
config.shader.decay = decaybackup;
clearInterval(interval)
interval = '';
});
also here is a read only link to my site if you need a visual of what im talking about and can also see any code I have added...
enter link description here
THANK YOU!!!
Use setInterval() to decrement decay back to decaybackup similar to the way you increment it during pointerdown.
let undecayInterval;
myshape.addEventListener('pointerup', function(event) {
config.shader.decay = decaybackup;
clearInterval(interval);
clearInterval(undecayInterval);
undecayInterval = setInterval(() => {
config.shader.decay -= 0.001;
if (config.share.decay <= decaybackup) {
clearInterval(undecayInterval);
}, 1);
}
});

Smooth scrolling on a click event

I'm trying to create a smooth scrolling effect using javascript library react. I don't want to use JQuery.
I want to archive when user clicks on a link that he goes to appropriate section of the page.
My handleScroll function is as follows :
handleScroll(ref, offsets, event){
event.preventDefault();
let offset = offsets[ref]; // this is where it needs to scroll for example 900
let activeLinks = {};
activeLinks[ref] = "active";
let start = new Date().getTime();
let time = 4000;
let offsetTo = this.state.offsetTo; //offsetTo is 0 on page load
let timer = setInterval(function() {
let step = Math.min(1,(new Date().getTime()-start)/time);
offsetTo = offsetTo + 40;
if(offsetTo >= offset) {
return;
}
window.scrollTo(0, offsetTo);
if( step == 1) clearInterval(timer);
},10);
this.setState({activeLinks: activeLinks}, () => timer);
}
This works pretty fine but only if I'm top of the page. When I click on the link it goes to the appropriate section with an animation.
But when I then click on some other link it works, but it starts from the top and not from the place where I am.
I need to find a way to set the offsetTo to the appropriate value, and then depending on it to go to the top or to the bottom.
Any idea how can I do that?
https://github.com/fisshy/react-scroll should do the trick.
see the examples, it's pretty straight forward.

Jquery - Carasol build finished and would like advice on best practice / neatening up my code

I have been building my own carasol over the past few days.
My Jquery is based on tutorials on the web and also from help and advice from SO.
I am not a Jquery guru just an enthusiast and think my code is a little sloppy, hence the post.
here is a link to the working code: http://jsfiddle.net/JHqBA/2/ (updated link)
basically what happens is:
if someone hits the page with a # values in the url it will show the appropriate slide and example would be www.hello.com#two, this would slide to slide two
if someone clicks the numbers it will show the appropriate slide
next and prev also slide through the slides.
The question is, is there anything i could have wrote better as i know there is alot of duplicate code.
I understand its a big ask but it would help me learn a little more (i think my code is a little old school)
if anyone has any questions please feel free to ask and ill answer what it does or is supposed to do.
Sluap
--- Edit ----
I have made only one aniamtion function now which has got rid of alot of duplicate code.
I have yet to look into on function but will do soon.
I would like to know more about the create a new function, outside of the jQuery ready block as i cant get this working or quite understand how i can get it to work sorry
any more tips would be great ill carry on working on this project till i am happy with it.
also is there a better way to write:
if ($slideNumber == 1) {
$('#prev').attr("class", "not_active")
$('#next').attr("class", "active")
}
else if ($slideNumber == divSum) {
$('#next').attr("class", "not_active");
$('#prev').attr("class", "active");
}
else {
$('#prev').attr("class", "active")
$('#next').attr("class", "active")
};
Jquery full:
$(document).ready(function () {
//////////////////////////// INITAL SET UP /////////////////////////////////////////////
//Get size of images, how many there are, then determin the size of the image reel.
var divWidth = $(".window").width();
var divSum = $(".slide").size();
var divReelWidth = divWidth * divSum;
//Adjust the image reel to its new size
$(".image_reel").css({ 'width': divReelWidth });
//set the initial not active state
$('#prev').attr("class", "not_active");
//////////////////////////// SLIDER /////////////////////////////////////////////
//Paging + Slider Function
rotate = function () {
var triggerID = $slideNumber - 1; //Get number of times to slide
var image_reelPosition = triggerID * divWidth; //Determines the distance the image reel needs to slide
//sets the active on the next and prev
if ($slideNumber == 1) {
$('#prev').attr("class", "not_active")
$('#next').attr("class", "active")
}
else if ($slideNumber == divSum) {
$('#next').attr("class", "not_active");
$('#prev').attr("class", "active");
}
else {
$('#prev').attr("class", "active")
$('#next').attr("class", "active")
};
//Slider Animation
$(".image_reel").animate({
left: -image_reelPosition
}, 500);
};
//////////////////////////// SLIDER CALLS /////////////////////////////////////////////
//click on numbers
$(".paging a").click(function () {
$active = $(this); //Activate the clicked paging
$slideNumber = $active.attr("rel");
rotate(); //Trigger rotation immediately
return false; //Prevent browser jump to link anchor
});
//click on next button
$('#next').click(function () {
if (!$(".image_reel").is(':animated')) { //prevent clicking if animating
var left_indent = parseInt($('.image_reel').css('left')) - divWidth;
var slideNumberOn = (left_indent / divWidth);
var slideNumber = ((slideNumberOn * -1) + 1);
$slideNumber = slideNumber;
if ($slideNumber <= divSum) { //do not animate if on last slide
rotate(); //Trigger rotation immediately
};
return false; //Prevent browser jump to link anchor
}
});
//click on prev button
$('#prev').click(function () {
if (!$(".image_reel").is(':animated')) { //prevent clicking if animating
var left_indent = parseInt($('.image_reel').css('left')) - divWidth;
var slideNumberOn = (left_indent / divWidth);
var slideNumber = ((slideNumberOn * -1) - 1);
$slideNumber = slideNumber;
if ($slideNumber >= 1) { //do not animate if on first slide
rotate(); //Trigger rotation immediately
};
}
return false; //Prevent browser jump to link anchor
});
//URL eg:www.hello.com#one
var hash = window.location.hash;
var map = {
one: 1,
two: 2,
three: 3,
four: 4
};
var hashValue = map[hash.substring(1)];
//animate if hashValue is not null
if (hashValue != null) {
$slideNumber = hashValue;
rotate(); //Trigger rotation immediately
return false; //Prevent browser jump to link anchor
};
});
Question and answer has been moved over to https://codereview.stackexchange.com/questions/8634/jquery-carasol-build-finished-and-would-like-advice-on-best-practice-neateni/8635#8635
1) Separation of Concerns
Start by refactorring your code in to more granular functions.
You can read more about SoF at http://en.wikipedia.org/wiki/Separation_of_concerns
Update:
E.g. Instead of having your reel resizing code inline, put it in it's own function, like this:
function setImageReelWidth () {
//Get size of images, how many there are, then determin the size of the image reel.
var divWidth = $(".window").width();
var divSum = $(".slide").size();
var divReelWidth = divWidth * divSum;
//Adjust the image reel to its new size
$(".image_reel").css({ 'width': divReelWidth });
}
This achieves 2 things:
a. First, it groups a block of code that is logically cohesive, removing it from the main code which results in a much cleaner code habitat.
b. It effectively gives a label to the code block via the function name that is descriptive of what it does, and therefore makes understanding of the code much simpler.
Later, you can also encapsulate the whole thing in it's own "class" (function) and you can move it into it's own js file.
2) The jQuery "on" function
Use the "on" function to attach your click events, rather than the "click" function.
http://api.jquery.com/on/
This has the added advantage of also binding it to future elements matching your selector, even though they do not exist yet.
3) The ready function
// I like the more succinct:
$(handler)
// Instead of:
$(document).ready(handler)
But you might like the more obvious syntax.
Those are just a few things to start with.
-- Update 1 --
Ok, StackOverflow is not really suited to a refactoring work in progress, but we'll make do. I think you should keep your original code block in your question, so that future readers can see where it started and how it systematically improved.
I would like to know more about the create a new function, outside of
the jQuery ready block as i cant get this working or quite understand
how i can get it to work sorry
I am not familiar with jsfiddle.net, but it looks cool and helpful, but might also be a bit confusing if you don't know what is going on. I am not sure I do :), but I think that script editor window results in a .js file that is automatically referenced by the html file.
So here is an example of a function defined outside of the ready block, but referenced from within.
function testFunction () {
alert ('it works');
}
$(document).ready(function () {
testFunction();
// ... other code
});
This should pop up an alert box that says, "it works" when the page is loaded.
You can try it for yourself.
Then, once you got that working, you can refactor other logically cohesive blocks of code into their own functions. Later you can wrap them all up into their own javascript 'class'. But we'll get to that.

Make overflow automatically go down every few seconds

I want that scroll would automatically go down a little bit every few seconds and that would expose more text. Is it possible to do that? By overflow I mean this: http://jsfiddle.net/Bnfkv/2/
You can use a timer that relaunches itself it there is anything left to do:
function scroll() {
$('#x').animate({ scrollTop: '+=5px' }, 100, function() {
if($('#x table').height() - this.scrollTop - $('#x').height() > 0)
setTimeout(scroll, 500);
});
}
scroll();
And an updated example: http://jsfiddle.net/ambiguous/2PpyJ/
Note that I added id="x" to your HTML to make it easier to reference the <div>.
var myElement = document.getElementById(.......); // or use jquery
var scrolling = setInterval(
function() {
//pick one:
//myElement.scrollBy(0,1); // if it's a textarea or something
//myElement.scrollTop = myElement.scrollTop+1; // if it's a DIV
},
10 // every 10ms
);
To stop it:
clearInterval(scrolling);

How to display a blinking / flashing link in html

I am in need a link that will flash every 500 milleseconds, for a duration of 5 seconds...
I remember long ago having a link like this, but deleted it because one could only click it when it was visible. Is there a workaround for that?
Try this:
<script type="text/javascript">
var col = new String();
var x=1;var y;
function blink()
{
if(x%2)
{
col = "rgb(255,0,0)";
}else{
col = "rgb(255,255,255)";
}
aF.style.color=col;x++;if(x>2){x=1};setTimeout("blink()",500);
}
</script>
<body onload="blink()">
<a id="aF" href="http://www.google.com"><b>*Google!*</b><br>
There is a JavaScript function in Script.aculo.us to do that : Have a look on Effect.Pulsate
There is CSS
text-decoration: blink
but that will blink your link all the time, you would need some javascript to change the style after 5 seconds.
Remember to always keep usability for all users in mind. Especially if you're making something flash at a certain frequency. Just be careful.
'A' quick JQuery UI version...
Links need CLASS 'flasher', and an ID
Will start on mouseover...and stop on mouseout.
Also add the secondarycolor as a hover to the 'A' link...it will help mask the initial interval delay at start.
var flashInterval;
var flasherId;
var firstColor = '#EF7F2C';
var secondaryColor = '#3296C8';
var flashTime = 300;
jQuery('a.flasher').mouseover(function() {
if(flasherId){ jQuery('#'+flasherId).animate({ color:firstColor},0); }//stop any previous flashing link
flasherId = jQuery(this).attr('id');//get id of current link
//set interval
flashInterval = setInterval(function(){ jQuery('#'+flasherId).animate({ color:secondaryColor},flashTime).animate({ color:firstColor},flashTime); },flashTime*2);
}).mouseout(function() {
clearInterval(flashInterval);//clear interval
jQuery('#'+flasherId).animate({ color:firstColor},0);//reset flasher
flasherId = '';//clear flasher var
});

Categories