this question is different to this one, which detect if a browser is currently active.
I would like to detect more types of user behaviors, thing like
read throughout the article from beginning to the end very quickly
read throughout the article from beginning to the end slowly
Read a few lines and leave
search a keyword inside the article and read the part contains that keyword
These are most likely to be done using Intervals and a little bit of window screen height.
For example, if the user scrolls down, you can get the value of their screen's Y-axis then trigger a new Time class, then as soon as the user reached the bottom of the page. Stop the timer and get the value through AJAX and save it to your database.
For example:
window.onscroll = function() {
if (document.body.scrollTop > 50 || document.documentElement.scrollTop > 50) {
var time = setInterval(savetimeEverySecond(), 1000);
}
if($(window).scrollTop() + $(window).height() == $(document).height()) {
//clearInterval()
//I have reached bikini bottom, might as well do my ajax
}
};
Related
I need to implement a scroll function in my site.
When I will scroll down, document will be scrolled until a fixed position, which I want.
For example:
$(“.scroll-block”).scrollTop(250);
I realized this function. Pseudo-code:
when (scrollTop > 0)
do (scrollTop(250))
But then scroll is fixed. And any scroll-actions doesn’t work.
But I have three block. And I want to keep the possibility to scroll to all three blocks.
How can I do that?
P.S.: sorry for my terrible English. It’s my first post on this platform for communication.
P.S.S.: and first topic on English language.
Register a scroll callback like so:
jQuery(window).scroll(scrollCallback);
In the callback you can get the scroll position and do whatever you want at specific heights.
function scrollCallback(){
//gets the current windows scroll top value
var scrollPos = jQuery(window).scrollTop();
//get the position of the top of the elements you want to trigger actions on.
var first = jQuery('the-element-you-want-to-select1').position().top;
var second = jQuery('the-element-you-want-to-select2').position().top;
if(scrollPos > first){
//do something for first height
}else if(scrollPos > second){
//do something for second height
}
..
..
}
I have this code for loading data. When user scrolls down over a half of screen, it continues to load data and append HTML to document. The problem is $(window).height() doesn't update on the fly after HTML changes so the condition expression goes wrong. How to fix it?
// Check scrollbar is down a half.
$(window).scroll(function() {
console.log("flag: " + flag);
console.log($(window).scrollTop());
console.log($(window).height());
if (($(window).scrollTop() > $(window).height() / 2)) {
if(flag == 0) {
console.log("Load data");
loadData(globalIndex, globalCount);
globalIndex += 40;
}
flag = 1;
} else {
flag = 0;
}
});
The height of your window isn't going to change unless you resize the browser screen. The problem with your formula is that in order to make it work, you'll need to load enough data to move your scrollbar back above the midpoint. If you don't, this formula will constantly return true, and you'll be calling loadData far more times than you care to.
As a potential workaround (depending on how long it takes to load your data), you can call loadData once your scrollbar reaches the bottom of your window. This condition will be true far less frequently than your current one, and it will only load data if your user is attempting to view it. If data loading is quick, then this is an easy solution. If it is a time-intensive process, and that's the reason you chose to load data once you got to the halfway point, then consider loading more data at a time and including a spinner or some other visual clue to inform the user that data is loading.
$(window).height()
will give you the browser's height (which is constant unless you resize your window). Try using:
$(document).height() - ($(window).height()/2);
instead...
I want to provide the user with the experience of scrolling through content, but I would like to load the content dynamically so the content in their viewing area is what they would expect, but there is no data above or below what they are looking at. For performance reasons, I don't want that data loaded. So when they scroll down new data gets loaded into their view, and data previously in their view is discarded. Likewise when scrolling up. The scroll bar should represent their location within the entire content though, so using "infinite scrolling" or "lazy loading" does not look like what I need.
My solution may be that I need to re-architect things. As of now, my project is a hex-viewer that allows you to drop a binary file onto it. I create html elements for every byte. This causes performance issues when you end up with a 1MB file (1,000,000+ DOM elements). One solution would be to not use DOM elements/byte but I think this will make other features harder, so I'd like to just not display as many DOM elements at once.
Make a div, set overflow to scroll or auto. As user scrolls you can change the content of the div.
You could look at yahoo mail (the JavaScript based one) to see how they do it (they add rows with email as you scroll).
You don't necessarily need custom scroll bars.
You could look for some code here for custom scroll bars:
http://www.java2s.com/Code/JavaScript/GUI-Components/Scrolltextwithcustomscollbar.htm
or here:
http://www.dyn-web.com/code/scroll/
I'm looking for an answer to this question as well so I'll share where I'm at with it.
I have a large amount of content I want to display vertically and have the user scroll through it. I can load it all into the DOM and scroll normally but that initial creation phase is horribly slow and scrolling can awfully slow also. Also, I will dynamically add to it as I stream more data in.
So I want the same thing which is to be able to dynamically populate and update a non-scrolling area with content. I want to make it seem as if the user is scrolling through that content and have a model (which has lots of data) that is kept off the DOM until it would be seen.
I figure I'll use a queue concept for managing the visible DOM elements. I'd store queueHeadIndex and queueTailIndex to remember what off-DOM elements are shown in the DOM. When the user scrolls down, I'd work out what whether the head of queue falls off the screen and if it does update queueHeadIndex and remove it's DOM element. Secondly I'd then work out whether I need to update queueTailIndex and add a new element to the DOM. For the elements currently in the DOM I'd need to move them (not sure if they need animation here or not yet).
UPDATE:
I've found this which seems to have some promise http://jsfiddle.net/GdsEa/
My current thinking is that there are two parts to the problem.
Firstly, I think I want to disable scrolling and have some sort of virtual scrolling. I've just started looking at http://www.everyday3d.com/blog/index.php/2014/08/18/smooth-scrolling-with-virtualscroll/ for this. This would capture all the events and enable me to programmatically adjust what's currently visible etc. but the browser wouldn't actually be scrolling anything. This seems to provide mouse wheel driven scrolling.
Secondly, I think I need to display a scroll bar. I've had a look at http://codepen.io/chriscoyier/pen/gzBsA and I'm searching around more for something that looks more native. I just want it to visually display where the scroll is and allow the user to adjust the scroll position by dragging the scroller.
Stackoverflow is insisting I paste code so here is some code from that codepen link above
var elem = document.getElementById('scroll-area'),
track = elem.children[1],
thumb = track.children[0],
height = parseInt(elem.offsetHeight, 10),
cntHeight = parseInt(elem.children[0].offsetHeight, 10),
trcHeight = parseInt(track.offsetHeight, 10),
distance = cntHeight - height,
mean = 50, // For multiplier (go faster or slower)
current = 0;
elem.children[0].style.top = current + "px";
thumb.style.height = Math.round(trcHeight * height / cntHeight) + 'px';
var doScroll = function (e) {
// cross-browser wheel delta
e = window.event || e;
var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
// (1 = scroll-up, -1 = scroll-down)
if ((delta == -1 && current * mean >= -distance) || (delta == 1 && current * mean < 0)) {
current = current + delta;
}
// Move element up or down by updating the `top` value
elem.children[0].style.top = (current * mean) + 'px';
thumb.style.top = 0 - Math.round(trcHeight * (current * mean) / cntHeight) + 'px';
e.preventDefault();
};
if (elem.addEventListener) {
elem.addEventListener("mousewheel", doScroll, false);
elem.addEventListener("DOMMouseScroll", doScroll, false);
} else {
elem.attachEvent("onmousewheel", doScroll);
}
I imagine I'll have one class that listens to scroll events by either the virtual scroll method or the ui and then updates the ui scroller and the ui of the content I'm managing.
Anyway, I'll update this if I find anything more useful.
I think avoiding using DOM elements/byte is going to be the easier solution for me than creating a fake scrolling experience.
UPDATE: I ultimately solved this as explained here: Javascript "infinite" scrolling for finite content?
You're taking about using some serious javascript, specifically AJAX and JSON type elements. There is no easy answer to your questions. You'd need to do a lot of R&D on the subject.
I'm trying to create my own custom parallax plugin so that I am able to choose the direction the items transition off the screen and I'm just stuck at making sure that no matter how a user scrolls and no matter of the size of the window that the object disappears at the correct point.
Currently I have:
var lastScrollTop = 0;
var logoStartPos = $('.bg-logo').position().left;
$(function(){
$(window).scroll(function(){
var st = $(this).scrollTop();
if (st > lastScrollTop){
if($('.bg-logo').is(':in-viewport'))
$('.bg-logo').css({'left':($('.bg-logo').position().left+10) + "px"});
} else {
if($('.bg-logo').is(':in-viewport') && logoStartPos < $('.bg-logo').position().left)
$('.bg-logo').css({'left':($('.bg-logo').position().left-10) + "px"});
}
lastScrollTop = st;
});
});
As you can guess this only moves the item right until it goes off screen. This way has varied results because if I use the scroll wheel it take longer to disappear to if I use the scroll bar. I also have another problem in that if I use a mixture or have a different view port I get an different result all together.
Any tips or pointers to achieve the result I'm after?
An working example of my code is at http://motoring.egl.me.uk
Thanks Matt
A bit dated, but FYI...
In your jQuery initialize or ready event, you need to initialize each section, article, item or whatever it is (item.each) to instantiate a scroll function, so that each one has it's own scroll function.
this.each(function(index) {
Then in scroll function, only handle the event, if it is the 'current' section. You will need some way to determine which item is the 'current' one. Often this is done by saving each item's window size into a global array, and then using that compare to the current location.
Something like: (The way you designed your code will likely be very different)
// If this section is in view
if ( ($window.scrollTop() + $window.height()) > (topOffset) &&
( (topOffset + $self.height()) > $window.scrollTop() ) )
In this way, once one item goes off the screen, the next item should become 'current' and continue the scrolling.
I coded for a chat script and all the issue is with scrolling DIV layer. I downloaded few chat scripts and found the below after careful observation.
When ever a new line of chat is added, scroll bar doesn't scrolls down after chat line is added. Its adding to the bottom of the DIV layer as the scroll doesn't make any kind of disturbance while making it.
What I did:
Before I used javascript to scroll down for every fixed interval. Doing this I am unable to manually scroll up to view past lines(due to interval refresh scroll bar moves to set position). Later I coded for a javascript that can scrolls down OnClientClick but doing this I can only able to scroll down Chat sender side but it cannot scroll down at Chat receiver side when a new chat line is added.
I downloaded many chat scripts and checked how this particular issue is managed but I couldn't find any solution for it. I fairly guess that its the work of jQuery (not sure) can anybody tell me how to fix this issue?
I am sorry if you failed to understand my issue as I am unable to explain it in more detailed than as above. However I can give you more information on request.
Languages I am using are ASP.NET, AJAX update panels, timer ticks for updating div with new values, javascripts are till now used only to scroll down the element.
Your chat 'screen' should look like this:
<div id="chat">
<div class="wrapper">
<!-- chat messages go here -->
</div>
</div>
Put overflow-y: auto on the chat, but leave the wrapper as it is. Create on function that runs at an interval and add or removes a class "atBottom" to chat 'screen' based on value returned by $('#chat').scrollTop() method.
monitor = function() {
var $this = $(this),
wrap = $this.find('.wrapper'),
height = $this.height(),
maxScroll = wrap.height() - height,
top = $this.scrollTop();
if (maxScroll === top) {
$this.addClass('atBottom');
} else {
$this.removeClass('atBottom');
}
}
window.setInterval(function() {
monitor.call($('#chat').get(0));
}, 350);
Then you need to bind an event 'addMessage' that works like so:
$('#chat').bind('addMessage', function(e, message) {
var $this = $(this),
// store whether it's at the bottom before appending the message
scroll = $this.hasClass('atBottom');
// then append the message
$this.find('.wrapper').append(message);
if (scroll) {
// measure the new maxScroll and scroll to it.
var wrap = $this.find('.wrapper'),
height = $this.height(),
maxScroll = wrap.height() - height
$this.scrollTop(maxScroll);
}
})
$('button').click(function() {
$('#chat').trigger('addMessage', 'asdgagasdg<br/>');
});
Here's an example:
http://jsfiddle.net/WVLE2/