Auto Scroll down but stop when user scrolls - javascript

I have a chat box where people will beable to add there own message to it but my problem is that when new messages are added it does not scroll down to reveal the new message.
I fixed this by using this code
$('.panel-body').scrollTop($('.panel-body').height()*$('.panel-body').height());
(panel-body is the class of my scrolling div)
But the problem with this is that if a user wants to scroll back up at previous messages he or she will be forced back down to the bottom. What would be the best way to stop "auto scrolling" when the user scrolls but when the user scrolls back down or just loads the page it would start up again.
function addMsg(is_admin, name, mes, time) {
var newDiv = document.createElement("div");
newDiv.className = "row";
var p = document.createElement("p");
p.className = "text-muted name";
var p2 = document.createElement("p");
var text = document.getElementById("start");
var hr = document.createElement("hr");
var times = document.createElement("p")
text.appendChild(newDiv);
newDiv.appendChild(p);
p.innerHTML = name + ":";
newDiv.appendChild(p2);
newDiv.appendChild(times)
times.className = "time";
if (is_admin) {
p.style = "color: red;";
p2.innerHTML = mes;
times.innerHTML = "time: " + time;
} else {
p2.innerHTML = mes;
times.innerHTML = time;
}
newDiv.appendChild(hr);
This is my addMsg Function that i have already created

Here's a quick attempt I threw together.
By subtracting the element's height() (jQuery) from its scrollHeight (JS) and comparing that to the user's scrollTop (jQuery scroll position), we can determine if we're currently at the bottom of the scrollable container before the new message appears.
If we are at the bottom, then keep the user down there by setting the new scrollTop. Otherwise, don't change anything. Hope this helps!
Live demonstration:
function newMsg() {
// FOR DEMO (naming each message)
var count = $('.msg').length;
// shouldScroll will be true if we're at the bottom of the
// scrollable container before the new message appears
var $panel = $('.panel-body');
var shouldScroll = $panel[0].scrollHeight - $panel.height() <= $panel.scrollTop();
// this is where you append a new message to the container
$panel.append('<div class="msg">Message ' + count + '</div>');
// if we were at the bottom before the new message,
// then scroll to the new bottom of the container
if (shouldScroll) {
$panel.scrollTop($panel[0].scrollHeight);
}
}
// FOR DEMO (new message every .5 seconds)
setInterval(newMsg, 500);
.panel-body {
border: 1px solid #000;
overflow: auto;
width: 200px;
height: 200px;
}
.msg {
border-bottom: 1px solid #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="panel-body"></div>

Related

Inner element's positioning being overwritten by parent div's pos

I have an div that sticks to the bottom of a page. Inside that div, a button pops up (after 2 seconds) that the user can click to close the housing div.
The housing div has a fixed position and the button is absolute with top:0;right:0;. But when the element is displayed (as shown in the snippet), the styling for the button changes to "font-size: 12px; font-family: tahoma; right: 0px; color: rgb(85, 85, 85); visibility: visible;", removing the original absolute. If I manually add it into it using the inspect element, it goes to the right as intended. But why does it not show in the first place?
adh('test', 320, 100);
function adh(dfp, len, hgt) {
var adhBase = document.createElement('div');
adhBase.id = dfp;
if (false) {
// is there mobile horizon???
} else {
adhBase.style = "z-index:9999;height:" + hgt + "px;position:fixed;bottom: 0;left: 50%;width:" + len + "px;transform: translateX(-50%);box-sizing: border-box;background-color:lightblue;";
}
document.body.appendChild(adhBase);
// Close button
var adhClose = document.createElement('button');
adhClose.id = 'closeBtn';
adhClose.style = 'font-size:12px;font-family:tahoma;position:absolute:top:0;right:0;border:1 px solid #ccc;color: #555;box-sizing:border-box:text-decoration:none;visibility:hidden';
adhClose.innerHTML = 'close';
document.getElementById(dfp).appendChild(adhClose);
console.log('3');
// function that closes the button
document.getElementById('closeBtn').addEventListener('click', function(e) {
e.preventDefault();
this.parentNode.style.display = 'none';
});
setTimeout(function() {
adhClose.style.visibility = "visible"
}, 2000);
}

Using two mouse events after each other

I am creating a canvas alike without using canvas tag , by creating new div each time mouse is down, i can't figure out how to run a second event.
Like mousedown then mousemove event where the seconed event occur only after the first one is true?
also if you can help with the offset coordinates
var paintbox = document.getElementById("canvas");
var start = function() {
paintbox.addEventListener("mousedown", drawOnCanvas);
};
var newColor = document.getElementById("colorPick");
var drawOnCanvas = function() {
var newClick = document.createElement("div");
newClick.setAttribute("id", "smallDiv");
newClick.style.backgroundColor = newColor.value;
newClick.style.width = "10px";
newClick.style.height = "10px";
newClick.style.position = "absolute";
paintbox.appendChild(newClick);
}
Set the handler on the mousemove event instead of mousedown and in the handler check whether the mouse button is down.
It would be better to move the 10px/position style settings in a CSS class. Also, don't generate elements with the same id attribute value: that generates invalid HTML. Use a class instead.
For the positioning you can use the pageX and pageY properties of the event object.
Finally, as the events will be triggered on the small divs when you make small moves, an extra check might be necessary to verify the mouse is still in the paint box.
var paintbox = document.getElementById("canvas");
var start = function() {
paintbox.addEventListener("mousemove", drawOnCanvas);
};
var newColor = document.getElementById("colorPick");
var drawOnCanvas = function(e) {
if ((e.buttons & 1) === 0) return; // Mouse button is not down
// Extra check to see we are well within the box boundaries:
var box = paintbox.getBoundingClientRect();
if (e.clientX - 5 < box.left || e.clientX + 5 > box.right
|| e.clientY - 5 < box.top || e.clientY + 5 > box.bottom) return;
var newClick = document.createElement("div");
newClick.className = "smallDiv"; // Don't create duplicate ID; put CSS in class
newClick.style.backgroundColor = newColor.value;
paintbox.appendChild(newClick);
newClick.style.left = (e.pageX-5) + "px";
newClick.style.top = (e.pageY-5) + "px";
}
start();
#canvas {
height: 150px;
width: 300px;
border: 1px solid;
display: inline-block;
margin: 10px;
}
.smallDiv {
width: 10px;
height: 10px;
position: absolute;
}
Color: <input id="colorPick" type="color"><br>
<div id="canvas"></div>

JS style.marginLeft & marginRight = 'auto' not working

Using the Yahoo Weather API.
When trying to set the style margins via JS, nothing happens.
Here is my script:
<script>
var cBackFunction = function (data) {
console.log(data);
var location = data.query.results.channel.location;
var condition = data.query.results.channel.item.condition;
var wind = data.query.results.channel.wind;
var units = data.query.results.channel.units;
var link = data.query.results.channel.link;
var lastUpdated = data.query.results.channel.lastBuildDate;
var conditionCode = condition.code;
var conditionText = condition.text;
var img = document.createElement("IMG");
img.src = "https://s.yimg.com/zz/combo?a/i/us/we/52/" + conditionCode + ".gif";
img.style.marginLeft = "140px";
document.getElementById('Weather-Description2').appendChild(img);
document.getElementById('Weather-Location2').innerHTML = location.city;
document.getElementById('Weather-Region2').innerHTML = location.region;
document.getElementById('Weather-Temp2').innerHTML = condition.temp;
document.getElementById('Weather-Unit2').innerHTML = units.temperature;
document.getElementById('Weather-WindSpeed2').innerHTML = wind.speed;
document.getElementById('Weather-Link2').href = link;
document.getElementById('lastUpdate2').innerHTML = lastUpdated;
document.getElementById('Weather-text2').innerHTML = "["+conditionText+"]";
document.getElementById('Weather-text2').style.marginLeft = 'auto'; //not working
document.getElementById('Weather-text2').style.marginRight = 'auto'; // not working
}
HTML:
<strong id="Weather-text2"></strong>
If I change the auto to a specific pixel like "100px" then it works.. can auto be used in JS for margins? The reason for auto on both marginLeft and marginRight is to auto-center the element. If so, how do I implement that correctly?
A <strong> element is, by default, display: inline.
Auto margins centre elements which are display: block (although since you would have width: auto as the default, this would have no practical effect unless you also reduced the width).
Set text-align: center on the nearest block ancestor element to centre the text.

why this javascript code don't work after i reload part of my page with ajax?

I have 3 files with php and js. in first file i load some information and show it to user, then user can change them. for show other information to user i reload part of my page with some code that they are in second php file. i put them in <div id='show_album'>my data</div> and change them with second php file.
for first run my javascript code work fine, but after reloading part of page it never work. what must i change in code that it work after reloading?!
this is part of code that can reload div element with ajax:
<select onchange="showList('showalbum.php?change=',this.value,'show_album')"><option value='1'>1</option> <option value='2'>2</option></select>
in this part of code that in first page i reload my div element with new data.
then in new data i have something like this:
size of picture: 460*345
that show picture link to user and when user click on it, with javascript i show it to user on this page and on my other information that user can close it.but now this rel="lightbox" don't work and when user click on link, this picture open in same window.
this is my javascript code and in <head> i define it:
/*
Table of Contents
-----------------
Configuration
Functions
- getPageScroll()
- getPageSize()
- pause()
- getKey()
- listenKey()
- showLightbox()
- hideLightbox()
- initLightbox()
- addLoadEvent()
Function Calls
- addLoadEvent(initLightbox)
*/
//
// Configuration
//
// If you would like to use a custom loading image or close button reference them in the next two lines.
var loadingImage = './LightBox/loading.gif';
var closeButton = './LightBox/close.gif';
//
// getPageScroll()
// Returns array with x,y page scroll values.
// Core code from - quirksmode.org
//
function getPageScroll(){
var yScroll;
if (self.pageYOffset) {
yScroll = self.pageYOffset;
} else if (document.documentElement && document.documentElement.scrollTop){ // Explorer 6 Strict
yScroll = document.documentElement.scrollTop;
} else if (document.body) {// all other Explorers
yScroll = document.body.scrollTop;
}
arrayPageScroll = new Array('',yScroll)
return arrayPageScroll;
}
//
// getPageSize()
// Returns array with page width, height and window width, height
// Core code from - quirksmode.org
// Edit for Firefox by pHaez
//
function getPageSize(){
var xScroll, yScroll;
if (window.innerHeight && window.scrollMaxY) {
xScroll = document.body.scrollWidth;
yScroll = window.innerHeight + window.scrollMaxY;
} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
xScroll = document.body.scrollWidth;
yScroll = document.body.scrollHeight;
} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
xScroll = document.body.offsetWidth;
yScroll = document.body.offsetHeight;
}
var windowWidth, windowHeight;
if (self.innerHeight) { // all except Explorer
windowWidth = self.innerWidth;
windowHeight = self.innerHeight;
} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
windowWidth = document.documentElement.clientWidth;
windowHeight = document.documentElement.clientHeight;
} else if (document.body) { // other Explorers
windowWidth = document.body.clientWidth;
windowHeight = document.body.clientHeight;
}
// for small pages with total height less then height of the viewport
if(yScroll < windowHeight){
pageHeight = windowHeight;
} else {
pageHeight = yScroll;
}
// for small pages with total width less then width of the viewport
if(xScroll < windowWidth){
pageWidth = windowWidth;
} else {
pageWidth = xScroll;
}
arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight)
return arrayPageSize;
}
//
// pause(numberMillis)
// Pauses code execution for specified time. Uses busy code, not good.
// Code from http://www.faqts.com/knowledge_base/view.phtml/aid/1602
//
function pause(numberMillis) {
var now = new Date();
var exitTime = now.getTime() + numberMillis;
while (true) {
now = new Date();
if (now.getTime() > exitTime)
return;
}
}
//
// getKey(key)
// Gets keycode. If 'x' is pressed then it hides the lightbox.
//
function getKey(e){
if (e == null) { // ie
keycode = event.keyCode;
} else { // mozilla
keycode = e.which;
}
key = String.fromCharCode(keycode).toLowerCase();
if(key == 'x'){ hideLightbox(); }
}
//
// listenKey()
//
function listenKey () { document.onkeypress = getKey; }
//
// showLightbox()
// Preloads images. Pleaces new image in lightbox then centers and displays.
//
function showLightbox(objLink)
{
// prep objects
var objOverlay = document.getElementById('overlay');
var objLightbox = document.getElementById('lightbox');
var objCaption = document.getElementById('lightboxCaption');
var objImage = document.getElementById('lightboxImage');
var objLoadingImage = document.getElementById('loadingImage');
var objLightboxDetails = document.getElementById('lightboxDetails');
var arrayPageSize = getPageSize();
var arrayPageScroll = getPageScroll();
// center loadingImage if it exists
if (objLoadingImage) {
objLoadingImage.style.top = (arrayPageScroll[1] + ((arrayPageSize[3] - 35 - objLoadingImage.height) / 2) + 'px');
objLoadingImage.style.left = (((arrayPageSize[0] - 20 - objLoadingImage.width) / 2) + 'px');
objLoadingImage.style.display = 'block';
}
// set height of Overlay to take up whole page and show
objOverlay.style.height = (arrayPageSize[1] + 'px');
objOverlay.style.display = 'block';
// preload image
imgPreload = new Image();
imgPreload.onload=function(){
objImage.src = objLink.href;
// center lightbox and make sure that the top and left values are not negative
// and the image placed outside the viewport
var lightboxTop = arrayPageScroll[1] + ((arrayPageSize[3] - 35 - imgPreload.height) / 2);
var lightboxLeft = ((arrayPageSize[0] - 20 - imgPreload.width) / 2);
objLightbox.style.top = (lightboxTop < 0) ? "0px" : lightboxTop + "px";
objLightbox.style.left = (lightboxLeft < 0) ? "0px" : lightboxLeft + "px";
objLightboxDetails.style.width = imgPreload.width + 'px';
if(objLink.getAttribute('title')){
objCaption.style.display = 'block';
//objCaption.style.width = imgPreload.width + 'px';
objCaption.innerHTML = objLink.getAttribute('title');
} else {
objCaption.style.display = 'none';
}
// A small pause between the image loading and displaying is required with IE,
// this prevents the previous image displaying for a short burst causing flicker.
if (navigator.appVersion.indexOf("MSIE")!=-1){
pause(250);
}
if (objLoadingImage) { objLoadingImage.style.display = 'none'; }
objLightbox.style.display = 'block';
// After image is loaded, update the overlay height as the new image might have
// increased the overall page height.
arrayPageSize = getPageSize();
objOverlay.style.height = (arrayPageSize[1] + 'px');
// Check for 'x' keypress
listenKey();
return false;
}
imgPreload.src = objLink.href;
var e = document.getElementById('gand');
e.style.display = 'none';
}
//
// hideLightbox()
//
function hideLightbox()
{
// get objects
objOverlay = document.getElementById('overlay');
objLightbox = document.getElementById('lightbox');
// hide lightbox and overlay
objOverlay.style.display = 'none';
objLightbox.style.display = 'none';
// disable keypress listener
document.onkeypress = '';
var e = document.getElementById('gand');
e.style.display = 'block';
}
//
// initLightbox()
// Function runs on window load, going through link tags looking for rel="lightbox".
// These links receive onclick events that enable the lightbox display for their targets.
// The function also inserts html markup at the top of the page which will be used as a
// container for the overlay pattern and the inline image.
//
function initLightbox()
{
if (!document.getElementsByTagName){ return; }
var anchors = document.getElementsByTagName("a");
// loop through all anchor tags
for (var i=0; i<anchors.length; i++){
var anchor = anchors[i];
if (anchor.getAttribute("href") && (anchor.getAttribute("rel") == "lightbox")){
anchor.onclick = function () {showLightbox(this); return false;}
}
}
// the rest of this code inserts html at the top of the page that looks like this:
//
// <div id="overlay">
// <img id="loadingImage" />
// </div>
// <div id="lightbox">
// <a href="#" onclick="hideLightbox(); return false;" title="Click anywhere to close image">
// <img id="closeButton" />
// <img id="lightboxImage" />
// </a>
// <div id="lightboxDetails">
// <div id="lightboxCaption"></div>
// <div id="keyboardMsg"></div>
// </div>
// </div>
var objBody = document.getElementsByTagName("body").item(0);
// create overlay div and hardcode some functional styles (aesthetic styles are in CSS file)
var objOverlay = document.createElement("div");
objOverlay.setAttribute('id','overlay');
objOverlay.onclick = function () {hideLightbox(); return false;}
objOverlay.style.display = 'none';
objOverlay.style.position = 'absolute';
objOverlay.style.top = '0';
objOverlay.style.left = '0';
objOverlay.style.zIndex = '90';
objOverlay.style.width = '100%';
objBody.insertBefore(objOverlay, objBody.firstChild);
var arrayPageSize = getPageSize();
var arrayPageScroll = getPageScroll();
// preload and create loader image
var imgPreloader = new Image();
// if loader image found, create link to hide lightbox and create loadingimage
imgPreloader.onload=function(){
var objLoadingImageLink = document.createElement("a");
objLoadingImageLink.setAttribute('href','#');
objLoadingImageLink.onclick = function () {hideLightbox(); return false;}
objOverlay.appendChild(objLoadingImageLink);
var objLoadingImage = document.createElement("img");
objLoadingImage.src = loadingImage;
objLoadingImage.setAttribute('id','loadingImage');
objLoadingImage.style.position = 'absolute';
objLoadingImage.style.zIndex = '150';
objLoadingImageLink.appendChild(objLoadingImage);
imgPreloader.onload=function(){}; // clear onLoad, as IE will flip out w/animated gifs
return false;
}
imgPreloader.src = loadingImage;
// create lightbox div, same note about styles as above
var objLightbox = document.createElement("div");
objLightbox.setAttribute('id','lightbox');
objLightbox.style.display = 'none';
objLightbox.style.position = 'absolute';
objLightbox.style.zIndex = '100';
objBody.insertBefore(objLightbox, objOverlay.nextSibling);
// create link
var objLink = document.createElement("a");
objLink.setAttribute('href','#');
objLink.setAttribute('title','براي بستن کليک کنيد');
objLink.onclick = function () {hideLightbox(); return false;}
objLightbox.appendChild(objLink);
// preload and create close button image
var imgPreloadCloseButton = new Image();
// if close button image found,
imgPreloadCloseButton.onload=function(){
var objCloseButton = document.createElement("img");
objCloseButton.src = closeButton;
objCloseButton.setAttribute('id','closeButton');
objCloseButton.style.position = 'absolute';
objCloseButton.style.zIndex = '200';
objLink.appendChild(objCloseButton);
return false;
}
imgPreloadCloseButton.src = closeButton;
// create image
var objImage = document.createElement("img");
objImage.setAttribute('id','lightboxImage');
objLink.appendChild(objImage);
// create details div, a container for the caption and keyboard message
var objLightboxDetails = document.createElement("div");
objLightboxDetails.setAttribute('id','lightboxDetails');
objLightbox.appendChild(objLightboxDetails);
// create caption
var objCaption = document.createElement("div");
objCaption.setAttribute('id','lightboxCaption');
objCaption.style.display = 'none';
objLightboxDetails.appendChild(objCaption);
// create keyboard message
var objKeyboardMsg = document.createElement("div");
objKeyboardMsg.setAttribute('id','keyboardMsg');
objKeyboardMsg.innerHTML = 'براي بستن کليد <kbd>x</kbd> را فشار دهيد';
objLightboxDetails.appendChild(objKeyboardMsg);
}
//
// addLoadEvent()
// Adds event to window.onload without overwriting currently assigned onload functions.
// Function found at Simon Willison's weblog - http://simon.incutio.com/
//
function addLoadEvent(func)
{
var oldonload = window.onload;
if (typeof window.onload != 'function'){
window.onload = func;
} else {
window.onload = function(){
oldonload();
func();
}
}
}
addLoadEvent(initLightbox); // run initLightbox onLoad
and i have css for this js that it is not importat but i write it here:
#lightbox {
background-color: #eee;
padding: 10px;
border-bottom: 2px solid #666;
border-right: 2px solid #666;
}
#lightboxDetails {
font-size: 0.8em;
padding-top: 0.4em;
}
#lightboxCaption {
float: left;
}
#keyboardMsg {
float: right;
}
#closeButton {
top: 5px;
right: 5px;
}
#lightbox img {
border: none;
clear: both;
}
#overlay img {
border: none;
}
#overlay {
background: url(../LightBox/overlay.png);
}
* html #overlay {
background-color: #000;
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader( src="../LightBox/overlay.png", sizingMethod="scale");
filter: alpha(opacity=70);
opacity: 0.7;
}
i think this code just run one time on window.load() and after i reload part of page it can't load again and don't work.
how i can resolve this problem?
tnks for reading my question...
Because to new html elements added after you need to recall all functions that work with it, for example recall functions that is called on document is created
When you get result from ajax and put it on html page, after write initLightbox();
You need to add initLightbox() here and change them with second php file. for first run my javascript
But you not write that code and I can't help you.
I can say only, put initlightbox after code where you receive response with ajax after lines where you insert new html elements.

Dynamic div in Javascript

I need to implement a dynamic div that pops up for each user. I need it to float over a Google map and each new div would appear below the previous one. It would end up being a stack of users essentially. Right now I have a table that adds a new row each time, but I am having trouble referencing each individual cell. Any advice on how to dynamically create a new div and make the new div appear under the other one(s)? It will float in the bottom left corner of the screen. Any help would be great. Thanks!
EDIT:
Here is some code that will show a div by pressing a button. What do I need to add to make a new div appear under the previous one?
function creatediv(id, html, width, height, left, bottom) {
var newdiv = document.createElement('div');
newdiv.setAttribute('id', id);
if (width) {
newdiv.style.width = 200;
}
if (height) {
newdiv.style.height = 50;
}
if ((left || bottom) || (left && bottom)) {
newdiv.style.position = "fixed";
if (left) {
newdiv.style.left = left;
if (bottom) {
newdiv.style.bottom = bottom = "10";
}
}
newdiv.style.background = "#FFFFF";
newdiv.style.border = "4px solid #000";
if (html) { newdiv.innerHTML = html;
}
else {
newdiv.innerHTML = "nothing";
}
document.body.appendChild(newdiv);
}
}
</script>
</head>
<div>
<input type="button" onclick="creatediv(id, 'User 1', 'width', 'height', 'left', 'bottom')" value="Create Div"/>
</div>
</html>
Keep a record of the top/bottom etc of the previoisly made div. Also the z-index. Now simply set the top/etc of the new div to a slightly shifted value, and increment the z-index. Repeat.

Categories