This is the js that I have in my js file
function refreshChat()
{
//speed up by selecting the div only once
var shoutbox = $("#shoutbox");
//get the height of the scroll (if any)
var oldScrollH = shoutbox.attr("scrollHeight") - 20;
//the ajax request
$.ajax({
url: 'shoutbox/update.php',
//disable cache
cache: false,
success: function(html) {
//update the shoutbox
shoutbox.html(html);
//get the heigth of the scroll after the update
var newScrollH = shoutbox.attr("scrollHeight") - 20;
if(newScrollH > oldScrollH)
{
//*move* the scroll down using an animation :)
shoutbox.animate({scrollTop: newScrollH}, 1);
}
}
});
}
//set the refreshChat function to run every *refreshSeconds*
setInterval(refreshChat, refreshSeconds);
});
it works fine in Firefox and IE, but with Google Chrome it constantly flicks. It will scroll to the bottom on page load, but when it calls to the function refreshChat it moves back up about halfway up the div.
I also have this in my <head>
$(document).ready(function(){
//speed up by selecting the div only once
var shoutbox = $("#shoutbox");
//get the height of the scroll (if any)
var oldScrollH = shoutbox.attr("scrollHeight");
//the ajax request
$.ajax({
url: 'shoutbox/update.php',
//disable cache
cache: false,
success: function(html) {
//update the shoutbox
shoutbox.html(html);
//get the heigth of the scroll after the update
var newScrollH = shoutbox.attr("scrollHeight");
if(newScrollH > oldScrollH)
{
//*move* the scroll down using an animation :)
shoutbox.animate({scrollTop: newScrollH}, 1);
}
}
})
});
so that it will auto load the shoutbox on page load, could this be conflicting with it? It seems logical, but I don't want users to have to wait 3 seconds for the shoutbox to initially load.
You need to convert string to int.
scrollHeight is custom attribute and i guess its dynamically added so it must string thats why you need to cast it to int.
parseInt(shoutbox.attr("scrollHeight"));
try this, hope this will solve it.
Related
I am working on a chat module. I am using the setInterval() function to fetch chat history.
I have a scroll bar (shown after the send/receive operation) and then whenever I get a result from the database via AJAX then
the scroll bar should stay in the same position, however right now the scroll bar is going to the top of the messages.
How can I handle the AJAX response an keep the message list in a specific position?
var scrollTopPosition = $("div#chat_sc_in").scrollTop();
var scroll_l = $("div#chat_sc_in").scrollLeft();
alert('Height is ' + scrollTopPosition);
alert('Width is ' + scroll_l);
$.ajax({
type: 'POST',
url: "<?php echo base_url('Welcome/user_chat_fetch'); ?>",
data: '',
success: function(html) {
$('.user_chat_module').html(html);
$('.user_chat_module').scrollTop(scrollTopPosition);
}
});
The scrollTop will remain constant after even the height of div increases. The solution is to track the distance between the scrollTop and the bottom of the div when ever the user scrolls and assign the difference of the new height and the calculated value when new content get added.
<script>
var scrollDifference = 0;
$("div#chat_sc_in").scroll(event => {
scrollDifference = event.target.scrollHeight - event.target.scrollTop;
});
$.ajax({
type:'POST',
url:"<?php echo base_url('Welcome/user_chat_fetch'); ?>",
data:'',
success:function(html){
$('.user_chat_module').html(html);
var divThatHasScrollBar = $("div#chat_sc_in")[0];
divThatHasScrollBar.scrollTop = divThatHasScrollBar.scrollHeight - scrollDifference;
}});
</script>
I am currently working on a website with ajax support. Navigating through website and the browser's history works great, but there is one problem I cannot solve.
When the user presses the back button, the last page appears again. But although I set the vertical scroll position to the previous one via popstate event, it jumps back to top again...
function loadContent(nextContent, nextUrl, newPage = true) {
var currUrl = window.location.pathname;
currUrl = currUrl.slice(7,currUrl.length);
var scrollY = window.scrollY;
var prevContent = document.getElementById("page").innerHTML;
document.getElementById("page").innerHTML = nextContent;
if (newPage) {
// overwrite current history entry
history.replaceState({ content: prevContent, url: currUrl, scrollY: scrollY }, null, currUrl);
initPage();
window.scrollTo(0,0);
// write new entry
history.pushState({ content: nextContent, url: nextUrl, scrollY: 0 }, null, nextUrl);
} else {
initPage();
// scroll to previous scroll position
window.scrollTo(0,history.state.scrollY);
}
}
window.onpopstate = function(e) {
loadContent(e.state.content, e.state.url, false);
// page scrollY will be set in load, after page content was added
}
I know that the code works so far because earlier I've put an alert after window.scrollTo() and during the freeze I saw, that the page is on the correct position. But after continuing it jumped to the top. Is there maybe another (default) event, that scrolls to the top in the background?
Thanks for help
I fixed the problem now by changing the onpopstate function to the following:
window.onpopstate = function(e) {
loadContent(e.state.content, e.state.url, false);
// as previous window.scrollTo() have no effect, do it within a few millisecs again
setTimeout(function() {
window.scrollTo(0,history.state.scrollY);
}, 5);
}
Not really beautiful, but it works. If someone knows a clean fix or the reason why this effect happens, please share your knowledge!
jQuery(window).scroll( function(){
/* Check the location of element */
jQuery('.logoscrollbg').each( function(i){
var logo = jQuery(this).outerHeight();
var position = jQuery(window).scrollTop();
/* fade out */
if( position > logo ){
jQuery(this).animate({'opacity':'1'},100);
}else{ jQuery(this).animate({'opacity':'0'},100);}
});
});
Above is my script for a class (the header) with should blend in when the page is being scrolled down and blend out when you are on the top of the page, with other words the start.
I don't understand javascript at all, but I do a little php and I was wondering if someone could help me write there a elseif tag and later make the else tag so that is the page is loaded the class(.logoscrollbg) isn't visible and when u start scrolling it gets visible and when you get to the top it gets invisivle again :)
The script works like this right now: when I enter the site it shows the bar(bad), later when scrolling it stays or well is there(good), then when getting to top again it fades out(good).
The code inside your scroll event needs to be run when the page is loaded as well as when it scrolls.
jQuery(function() {
// object to hold our method
var scrollCheck = {};
// define and call our method at once
(scrollCheck.check = function() {
// only need to get scrollTop once
var logo, position = jQuery(window).scrollTop();
/* Check the location of element */
jQuery('.logoscrollbg').each(function() {
logo = jQuery(this).outerHeight();
/* fade out or in */
// cleaned this up a bit
jQuery(this).animate({'opacity': position > logo ? 1 : 0}, 100);
});
})();
jQuery(window).scroll(function(){
// call our method
scrollCheck.check();
});
});
It looks to me like this will only fire when you scroll. Try updating your js to this:
jQuery(window).on('scroll, load', function() {
/* Check the location of element */
jQuery('.logoscrollbg').each( function(i){
var logo = jQuery(this).outerHeight();
var position = jQuery(window).scrollTop();
/* fade out */
if( position > logo ){
jQuery(this).animate({'opacity':'1'},100);
}else{ jQuery(this).animate({'opacity':'0'},100);}
});
});
*note: You may want to fire the callback on document load instead of window.
I have an image embedded in a container with a background image to give the effect of scrolling within the page. Initially, I had the scrolling effect take place on page load, with this simple bit of script which worked perfectly.
$(window).on("load", function () {
$(".embedded_scroller_image").animate({ scrollTop: $('.embedded_scroller_image')[0].scrollHeight}, 2500, "easeInOutCubic");
}); // end on load
However, the element is too far down the page now and I want that animation to fire when the element enters 80% of the viewport. That part is also working fine with this code here (I'm using a scroll limiter to improve browser performance)
// limit scroll call for performance
var scrollHandling = {
allow: true,
reallow: function() {
scrollHandling.allow = true;
},
delay: 500 //(milliseconds) adjust to the highest acceptable value
};
$(window).on('scroll', function() {
var flag = true;
if(scrollHandling.allow) { // call scroll limit
var inViewport = $(window).height()*0.8; // get 80% of viewport
$('.embedded_scroller_image').each(function() { // check each embedded scroller
var distance = $(this).offset().top - inViewport; // check when it reaches offset
if ($(window).scrollTop() >= distance && flag === true ) {
$(this).animate({ scrollTop: $(this)[0].scrollHeight}, 2500, "easeInOutCubic"); //animate embedded scroller
flag = false;
}
});
} // end scroll limit
}); // end window scroll function
The problem is this: I want the autoscroll to happen once and then stop. Right now, it works on entering viewport, but if I then try to manually scroll the image, it keeps pushing back down or stutters. You can't get the element to scroll normally. I attempted to use the flag in the code to stop the animation, but couldn't get that to successfully work.
How can I have this animation fire when the element is 80% in the viewport, but then completely stop after one time?
Here is a codepen I mocked up as well http://codepen.io/jphogan/pen/PPQwZL?editors=001 If you scroll down, you will see the image element autoscroll when it enters the viewport, but if you try to then scroll that image up in its container, it won't work.
Thanks!
I have tweaked your script a bit:
// limit scroll call for performance
var scrollHandling = {
allow: true,
reallow: function() { scrollHandling.allow = true; },
delay: 500 //(milliseconds) adjust to the highest acceptable value
};
$(window).on('scroll', function() {
if(scrollHandling.allow) { // call scroll limit
var inViewport = $(window).height()*0.8; // get 80% of viewport
$('.embedded_scroller_image').each(function() { // check each embedded scroller
var distance = $(this).offset().top - inViewport; // check when it reaches offset
if ($(window).scrollTop() >= distance ) {
$(this).animate({ scrollTop: $(this)[0].scrollHeight}, 2500, "easeInOutCubic"); //animate embedded scroller
scrollHandling.allow = false;
}
});
} // end scroll limit
}); // end window scroll function
I have kicked out your flag and simply made use of scrollHandling.allow declared already.
Try if it works for you :)
Cheers!
I'm trying to make an image drop up/down from a menu whenever the user clicks on the menu image which hasonClick="move()"in the tag. So far The image starts at the top of the page, behind the menu, so it is hidden, then slides down as intended. However, after the image reaches it's stopping point, clicking the menu again does nothing at all when I test the page in both IE and Chrome. In Dreamweaver, the code executes as intended, with the ability to slide the image up after it reaches the bottom and back down again. I've tried changing the call to setInterval() because I assumed that is where the problem was but nothing seems to be working. Why does Dreamweaver execute the code properly but not Chrome or IE?
var onMusic=false;
var id;
function move() {
if(!onMusic) {
moveDown()
}
else {
moveUp()
}
}
function moveUp() {
top=100
id = setInterval(function() {
top-=10 // update parameters
document.getElementById('guitar').style.top = top + 'px' // show frame
if (top <= -500) {// check finish condition
onMusic=false
clearInterval(id)
}
}, 10) // draw every 10ms
}
function moveDown() {
var top=-500
id = setInterval(function() {
top+=10 // update parameters
document.getElementById('guitar').style.top = top + 'px' // show frame
if (top == 100) {// check finish condition
onMusic=true
clearInterval(id)
}
}, 10) // draw every 10ms
}
id is only visible from the scope of the moveDown function. Make it global so that you can call clearInterval(id) in moveUp.
Change
function moveDown() {
var top=-500
var id = setInterval(function() {
to
var id;
function moveDown() {
var top=-500
id = setInterval(function() {
And changing the dom every tenth of millisecond (.1) might be a little extrem...
I think the problem was:
top=100
// should be
var top = 100;
You can try in the console to see what I mean:
>top = 12
12
> top
Window {top: Window, window: Window, location: Location, Proxy: Object, external: Object…}
But I cleaned it up a little more in jsfiddle:
http://jsfiddle.net/pNh57/1/