How can I mimic GChat's scrollable area? - javascript

GChat keeps the textarea scrolled to the end when new text appears, however if the user scrolls away from the end, it waits until you've scrolled back down to continue this behavior.
Using just HTML, Javascript and JQuery, how could one mimic this behavior?

Every time you add data, execute something like:
this.scrollTop = this.scrollHeight;
This is just standard Javascript that forces you to scroll to the bottom. To only force someone to stay scrolled to the bottom when they're already at the bottom, do something like this:
var elem = document.getElementById('myElementName');
var atBottom = (elem.scrollTop >= (elem.scrollHeight - elem.clientHeight));
// add your text updates here
if(atBottom) elem.scrollTop = elem.scrollHeight;
Example at http://jsfiddle.net/xjmha/4/
(Ignore the other versions of the fiddle... I was failing with jQuery.)

try something like this :)
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<style type="text/css">
textarea {
height: 80px;
width: 450px;
}
</style>
<script type="text/javascript">
var foo = function(){
var t = document.getElementById('foo');
if(t['data-scrollinglocked'])return;
var h = t.scrollHeight;
t.scrollTop = h;
}
var moo = function(){
var t = document.getElementById('foo');
t.innerHTML = t.innerHTML + new Date()+"\n";
}
var init = function(){
// global scope ;)
mooInterval = setInterval("moo()",1000);
fooInterval = setInterval("foo()",500);
var t = document.getElementById('foo');
t['data-scrollinglocked'] = 0;
t.onmouseout = function(){
t['data-scrollinglocked'] = 0;
};
t.onmouseover = function(){
t['data-scrollinglocked'] = 1;
};
t.onclick = function(){
t['data-scrollinglocked'] = 1;
};
t.onblur = function(){
t['data-scrollinglocked'] = 1;
};
t.onfocus = function(){
t['data-scrollinglocked'] = 1;
};
t.onblur= function(){
t['data-scrollinglocked'] = 0;
};
}
</script>
</head>
<body>
<div class="foo"></div>
<textarea id="foo"></textarea>
<script>init();</script>
</body>
</html>

Related

How to auto-scroll to end of div only when it is already showing the last line?

There already is an answer for autoscrolling, but that has a problem. If the user has manually scrolled it up to read old logs, that code keeps auto-scrolling, interfering the user's reading. So, I want it to auto-scroll only when it is showing the last line (i.e., either the user has never scrolled it up, or scrolled it up and then scrolled down to the bottom). How can I determine that?
var output;
var i = 0;
function onLoad() {
output = document.getElementById("output");
onTimeout();
}
function onTimeout() {
i++;
var line = document.createElement("div");
line.innerText = "Log " + i;
output.appendChild(line);
var isShowingTheLastLine = true;
if (isShowingTheLastLine) {
output.scrollTop = output.scrollHeight;
}
setTimeout(onTimeout, 1000);
}
<body onload="onLoad()">
<div id="output" style="overflow-y:scroll; height:200px; width:300px; background:yellow"></div>
</body>
You can use the offsetHeight property in this case. output.scrollHeight - output.offsetHeight will be equal to output.scrollTop if the div is scrolled to the bottom. Sometimes the difference may not be that accurate. So you can keep a minimum amount check in the condition.
if(Math.floor(output.scrollHeight - output.offsetHeight) - Math.floor(output.scrollTop) < 5)
{
// the div is currently at the bottom
}
Full code:
var output;
var i = 0;
function onLoad() {
output = document.getElementById("output");
onTimeout();
}
function onTimeout() {
i++;
var line = document.createElement("div");
line.innerText = "Log " + i;
if (
Math.floor(output.scrollHeight - output.offsetHeight) -
Math.floor(output.scrollTop) < 5
) {
// the div is currently at the bottom
output.appendChild(line);
output.scrollTop = output.scrollHeight;
} else {
output.appendChild(line);
}
setTimeout(onTimeout, 1000);
}
onLoad();
<div id="output" style="overflow-y:scroll; height:200px; width:300px; background:yellow"></div>
Here is my suggestion
Click the output and it stops. Click the scrollbar and scroll up and you can read as long as you hold the mouse down
I also use eventListeners instead of inline events
let output;
let cnt = 0;
let tId;
let pause;
const onTimeout = () => {
var line = document.createElement("div");
line.innerText = `Log ${++cnt}`;
output.appendChild(line);
if (!pause) {
output.scrollTop = output.scrollHeight;
tId = setTimeout(onTimeout, 1000);
}
};
window.addEventListener("DOMContentLoaded", () => {
output = document.getElementById("output");
onTimeout();
output.addEventListener("mousedown", () => {
pause = true;
});
document.addEventListener("mouseup", () => {
if (pause) {
pause = false;
onTimeout();
}
})
})
<div id="output" style="overflow-y:scroll; height:200px; width:300px; background:yellow"></div>

Gradually show an image using Javascript with the CSS property opacity

I need some help with my code. The task is to show an image by using a button. But the image has to show gradually with the CSS property "opacity".
The image should start at opacity 0 and should end at opacity 1.
Our teacher suggests us using "parsefloat" so the strings from CSS could be recognized by JS as numbers.
I do not really know why my code is not working. I would really appreciate it if you could show me where my mistake is.
Here is my code:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Aufgabe 12.2</title>
<script>
var go = function() {
var opac = function(delay) {
var img = document.createElement("img");
img.src = "http://www.google.com/intl/en_com/images/logo_plain.png";
var level = 0;
var step = function(){
img.style.opacity = level;
if(level <= 1) {
level += .1;
setTimeout(step, delay);
}
}
step();
}
opac(100);
};
</script>
<body>
<input type = "button" onclick = "go();" value = "Click me"/>
</body>
</head>
</html>
your code almost works, the only problem is that after you create your img variable, you never append it to the document. You create the image and correctly make it fade in but it is not part of the document so it will not be rendered. To fix this, addIn this line, document grabs a reference to the whole HTML document, and .body references the body tag. The .appendChild tells it to add a child element, to the body.
Here is a working example:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Aufgabe 12.2</title>
<script>
var go = function () {
var opac = function (delay) {
var img = document.createElement('img');
img.src =
'http://www.google.com/intl/en_com/images/logo_plain.png';
document.body.appendChild(img);
var level = 0;
var step = function () {
img.style.opacity = level;
if (level <= 1) {
level += 0.1;
setTimeout(step, delay);
}
};
step();
};
opac(100);
};
</script>
<body>
<input type="button" onclick="go();" value="Click me" />
</body>
</head>
</html>
Here is a link with more information
You need to append the img node to the DOM:
const btn = document.querySelector("input")
btn.onclick = () => go(100)
var go = function(delay) {
var img = document.createElement("img");
img.src = "http://www.google.com/intl/en_com/images/logo_plain.png";
document.body.append(img)
var level = 0;
const step = function() {
img.style.opacity = level;
if (level <= 1) {
level += .1;
setTimeout(step, delay);
}
}
step();
}
<input type="button" value="Click me" />

Have to move variable from left to right in Javascript. Professor has up and down as sample

new to javascript and taking a college course for game programming. Only using notepad. Now I have to move an object, in this case just the letter "o" from left to right. My professor provides code for the object going up and down the screen so I tried just to switch the "top" with "left" but it still wont move.
Prof sample:
<!-- Microsoft Edge, IE10/11, FireFox, Chrome -->
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
var bH = document.documentElement.clientHeight; // return the browser’s height
function init() {
var m1 = document.getElementById("m1"); // m1 represent m1
var y = parseInt(m1.style.top); // y-coordinate of m1
if (y >= bH) {
y = 0;
} else {
y++;
}
m1.style.top = y + "px";
s1 = setTimeout("init()", 10); // wait 10 milliseconds and then call init
}
window.onload = function () {
init(); // onload event occurs right after a page is loaded
}
</script>
</head>
<body>
<span id="m1" style="position: absolute; top: 0px">o</span>
</body>
</html>
My attempt:
<!-- Chrome -->
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
var bW = document.documentElement.clientWidth;
function init() {
var o = document.getElementById("o");
var x = parseInt(o.style.left);
if (x >= bW) {
x = 0;
} else {
x++;
}
o.style.left = x + "px";
s1 = setTimeout("init()", 10);
}
window.onload = function () {
init();
}
</script>
</head>
<body>
<span id="o" style="position: absolute; left: 0px">o</span>
</body>
</html>
Two three mistakes
using ; after window.onload = function(); is wrong
Don't add the function inside " " like s1=setTimeout("init()", 10); (it will work otherwise also, but i can't correctly figure out why not working in your case)
Solution: (js part only)
var bW = document.documentElement.clientWidth;
function init() {
var o = document.getElementById("o");
var x = parseInt(o.style.left);
if (x >= bW){
x = 0;
}
else{
x++;
}
o.style.left = x + "px";
s1=setTimeout(init(), 10);
}
window.onload = function(){
init();
}

Moving a div right animation not working

I am trying implement a small animation on a div. Whenever we click on the div it has to move right. I wrote some code but it is not working. Could anyone please help me?
here is my code
<style type="text/css">
#animDiv
{
background-color:#6F0;
width:87px;
height:39px;
left:10px;
}
</style>
<script>
function $(id)
{
return document.getElementById(id);
}
function moveRight()
{
var elem = $("animDiv");
//var divPos = parseInt($("animDiv").style.left);
var divPos = $("animDiv").offsetLeft;
var divWid = $("animDiv").offsetWidth;
if(divPos+divWid < 700)
{
$("animDiv").style.left = $("animDiv").style.left+100+"px";
}
}
</script>
<body>
<div id="animDiv" onclick="moveLeft()">
</div>
</body>
try replacing this code
<div id="animDiv" onclick="moveLeft()">
with this code
<div id="animDiv" onclick="moveRight()">
and add style position:fixed; to your css.
There are several issues in your code:
You are calling the wrong function. It is declared moveRight()
You are attempting to change the left property which will have no affect on elements that are positioned statically.
The element will only nudge right one time. After that the value for your left property is something like 100px100px.
How is this:
function moveRight() {
var elem = $("animDiv");
//var divPos = parseInt($("animDiv").style.left);
var divPos = $("animDiv").offsetLeft;
var divWid = $("animDiv").offsetWidth;
if (divPos + divWid < 700) {
var curLeft = Number($("animDiv").style.left.replace("px", ""));
$("animDiv").style.left = (curLeft + 100) + "px";
}
}
JSFiddle

stop settimeout incremention for an animated div

I have a function which increments the css quality of the position of a div layer and need it to stop when it reaches a certain amount of percentage to either the right or left (depending on the layer).
I have tried to do an if statement with a greater than operator, but does not seem to work. Here is the code in full:
<html>
<head>
<title>Stelucir</title>
<style>
body {
background-color: white;
}
#bg-right {
background-color: black;
position: fixed;
top: 0;
bottom: 0;
left: 50%;
right: 0;
z-index: -1;
}
</style>
<script type="text/javascript">
var header = null; // object
var about = null; // object
var blog = null; // object
var forum = null; // object
var chat = null; // object
var home = null; // object
function doMove() {
header.style.right = parseInt(header.style.right)+1+'%';
about.style.left = parseInt(about.style.left)+1+'%';
blog.style.right = parseInt(blog.style.right)+1+'%';
forum.style.left = parseInt(forum.style.left)+1+'%';
chat.style.right = parseInt(chat.style.right)+1+'%';
home.style.left = parseInt(home.style.left)+1+'%';
setTimeout(doMove,30); // call doMove in 20msec
}
function init() {
header = document.getElementById('header');
about = document.getElementById('about');
blog = document.getElementById('blog');
forum = document.getElementById('forum');
chat = document.getElementById('chat');
home = document.getElementById('home');
doMove(); // start animating
}
window.onload = init;
</script>
</head>
<body>
<div id="bg-right"></div>
<div id="header" style = "position:absolute;right:25%;font-size:80px;">Stelucir</div>
<div id="about" style = "position:absolute;left:40%;font- size:40px;top:90px;color:white;">About</div>
<div id="blog" style = "position:absolute;right:40%;font-size:40px;top:130px;">Blog</div>
<div id="forum" style = "position:absolute;left:40%;font-size:40px;top:170px;color:white;">Forum</div>
<div id="chat" style = "position:absolute;right:40%;font-size:40px;top:210px;">Chat</div>
<div id="home" style = "position:absolute;left:40%;font-size:40px;top:250px;color:white;">Home</div>
</body>
</html>
Use a global boolean. Start it at true, and when it reaches whatever point you want, set it to false. In doMove check to see that this is true, and if it's false simply return.
setTimeout() returns a handle on the timer. you can then call clearTimeout() on this handle to stop the timer.
Make a global variable to store this
var timer = null;
...
function doMove() {
...
timer = setTimeout(...);
}
//somewhere else
clearTimeout(timer);
I would more suggest using an interval instead of multiple setTimeout call. Also both setInterval and setTimeout return a reference which can be used to stop them using clearInterval(ref) or clearTimeout(ref);
Here is a little fiddle that animate a box to the right and stop when it is there.
http://jsfiddle.net/JV35w/1/
var elem = document.getElementById('foo'),
startX = 0,
endX = 400,
move = function() {
elem.style.left = startX + 'px';
startX += 10;
if (endX === startX) {
startX = 0;
clearInterval(t);
};
},
doMove = function() {
t = setInterval(move);
},
t;
doMove();​
https://developer.mozilla.org/en/DOM/window.setTimeout
https://developer.mozilla.org/en/DOM/window.setInterval

Categories

Resources