Is there a script that will jump the page to the horizontal end.
A user can press "Home" and "End" on the keyboard to jump to the top and bottom of the webpage, but what about right and left?
How do I spare the user of the inconvenience of having to scroll to the far, far depths of the x scroll
Horizontal scroll is a somehow unfrequent situation, as naturally the browser will try to vertical scroll unless unresizable elements really overflow the visible area; I will thus assume you are more in an explicitly-horizontal design such as one of these: http://webdesignledger.com/inspiration/40-of-the-best-horizontal-scrolling-websites
In any case, the basic is the same: catch some key* event, and do what you want.
Catch the event and launch your scroll function:
document.body.addEventListener('keydown', scrollfct, true);
First caveat: 'keypress' will not catch special characters such as up/down etc., so use 'keydown' or 'keyup'
Now the scroll function:
function scrollfct(e) {
console.log(evt.keyCode); /* this will debug that your function is being called, and will help you get the keyCodes you want. Remove in production :-) */
var HOME_LEFT = 33; //HOME
var HOME_RIGHT = 34; //END
if (e.keyCode == HOME_LEFT) {
window.scroll(0,0);
};
if (e.keyCode == HOME_RIGHT) {
window.scroll(document.body.scrollWidth,0);
}
}
For window.scroll doc: https://developer.mozilla.org/en/Window.scroll
Second caveat: to be fully cross-browser, you'll have to do some homework.
If you want to deal with mousewheel too, or want some smooth scroll, check this out: http://paulicio.us/items/view/24/horizontal-page-scrolling-using-javascript or with jQuery: http://tympanus.net/codrops/2010/06/02/smooth-vertical-or-horizontal-page-scrolling-with-jquery/ OR just use HTML5 CSS Transitions.
Normally I'd say, pagination would save the user from scrolling all over the place, but there are a couple other techniques. You could include a "right" button that links to the ID of something at the right of the page. That would jump them there immediately. That would look like this
Goto the Right
. . .
<div id="overtotheright"> . . . </div>
Or in javascript, the following should work.
window.scrollTo(document.body.scrollWidth, 0);
Related
I created a menu that shows its sub-menu on hover using some CSS and jquery. Thing is, it acts a bit funny in case user hovers lots of times on the menu item. This is the URL: http://91.202.168.37/~ibi/, and this is the jquery code (inside document ready):
if ($(window).width()>991) //menu script desktop or laptop
{
$('#mob-main-menu > li.menu-item-has-children').hover(function(event){
event.preventDefault();
$(this).children('a').toggleClass('bold600');
$(this).children('a').siblings('.sub-menu').slideToggle();
});
}
else // menu script touch device
{
$('#mob-main-menu > li.menu-item-has-children').click(function(event){
if ($(this).children('a').siblings('.sub-menu').css('display') == 'none')
{
event.preventDefault();
console.log('hidden');
}
$(this).children('a').toggleClass('bold600');
$(this).children('a').siblings('.sub-menu').slideToggle();
});
}
I tried to use setTimeout() function but couldn't get it to work. can I limit the code to queue no more than 2 times, no matter how many hovers it counted? and than after x time to set it back to zero? any other idea to make it work better will be happily accepted.
try make animation with .stop() function it clears the animation queue so it should work correctly
$(this).children('a').siblings('.sub-menu').stop().slideToggle();
Context: I have a button on the top of the page in the header, and I want visitors to jump to the form section which is at a lower position on the same page. For some unchangeable factors, the form is partially hidden under the header after page jump, so I am thinking of creating a new div before the form and change the height of the div to push the form down after jumping. Then, when users scroll again on the page, the height should go back to 0.
Problem: When I click on the DemoButton for the first time, the div height doesn't change and the form goes under header, but the second time it works. I don't know how to fix that.
The basic html structure is shown as following:
<div>
<a href="#demoForm" id="DemoButton">
<button>request demo</button>
</a>
</div>
<div id="space"></div>
<from id="demoForm">...</form>
JavaScript:
window.onload = function comparison() {
window.addEventListener("scroll", reset, false);
var demo = document.getElementById('DemoButton');
demo.onclick = uniform;
}
function reset() {
document.getElementById('Space').style.height = '0';
}
function uniform() {
document.getElementById('Space').style.height = '160px';
};
I know a lot of people are using newer CSS for reactive headers these days. I believe it's done using media queries, and I might suggest researching it some more. (I have some experience, it was very easy and cool too.)
Ideally, you'd want something like this to happen in CSS without JavaScript at all. See if you can get it figured out that way.
Using very light Javascript, it seems the easiest thing to do would be to just offset the scroll by the height of the header once the button has been clicked. You can hard-code the header height or calculate it dynamically.
So...
;;;;;;;;;;;;;;
; $ = document ;
; id = 'getElementById' ;
;;;;;;;;;;;;;
onload = function (e)
{
$[id]('DemoButton')
. onclick = function offset(e)
{
document.body.scrollTop -= $[id]('Header').offsetHeight;
}
;
}
Notes
You may have to wrap it in a 5ms setTimeout. Easy enough.
I don't remember all the cross-browseryness. There might be a need to parseInt or use document.documentElement. But at least you don't have cross-browser scroll events to deal with now, so this should be nice.
The Goal
So I have a list of <div>s all in a single column layout that have either the class "active" or "inactive". The active class shows a graphic to the right of the item and the inactive class doesn't. I have it setup so that hitting the up or down arrow key moves the "active" class (and the graphic with it) to the previous or next item. It isn't animated, but you can visually see the graphic disappearing and reappearing on the tag above or below.
Now I'd like to have the page scroll down on arrow keypress so that the top edge of the item is always in the same spot. Since the element list is larger than the page window, it's necessary to automatically scroll the browser so that the selected <div> is always in the center of the screen...
The Code
//Paging through items with arrow keys
theWindow.keydown(function (e) {
var key = e.keyCode,
oldItem = $('li.active')
if ((key === 40 && oldItem.next().length) || (key === 38 && oldItem.prev().length)) {
var theWindowMod = (window.innerHeight / 2) + 43,
theHTML = $('html'),
theDetail = $('.detail')
theHTML.addClass('notransition')
if (key === 40 && oldItem.next().length) {
oldItem.removeClass('active').next().addClass('active')
} else if (key === 38 && oldItem.prev().length) {
oldItem.removeClass('active').prev().addClass('active')
}
var newItem = $('li.active')
window.scroll(0, newItem.offset().top - theWindowMod)
e.preventDefault()
$('.detail-inner.active').fadeOut(0).removeClass('active')
$('section.active, .tab.active').removeClass('active')
newItem.find('.tab').add(theDetail).addClass('active')
theDetail.find('.detail-' + newItem.attr('class').split(' ')[0]).addClass('active').fadeIn(0)
setTimeout(function () {
theHTML.removeClass('notransition')
}, 1)
}
});
The Problem
The problem is that in all versions of Safari but no other browser, the window.scroll method is just a bit behind the CSS class switching performance wise. What happens is they end up in two different redraw events and it looks like the page is 'glitching' when you scroll down because you can briefly see the graphic to the right of the next element before the browser scrolls down.
The Live Demo
You can view it live here:
http://hashtag.ly/#minecraft
Use the arrow keys to page through items. Notice the jump. How should I go about resolving this?
I think a solution that avoids the issue is your best bet.
From a UX perspective, when I'm browsing a site, I don't like it when the site usurps control of the scroll position.
Also, for people with tall-ish browsers (like me) currently there can be a lot of white real-estate between the details and the selected post. (see screenshot)
My recommendation is to change the design so the details show up next to the selected post and let the user do the scrolling. Controlling the locaiton of the details with CSS, so they're next to the selected post, will put it in the same render-cycle as everything else.
The details being closer to the selected post might look something like this:
Update:
Come to think of it, AOL's email client Alto has the UX that you've implemented. In Alto, the left column does scroll automatically if you browse with the keys. But, you're not actually scrolling, they're adding content into the container element and bringing it into view (I forget what this is called... virtualization?). It looks like they're managing all the scroll-related visuals and behavior, themselves, and are not using the native functionality. So, it's all JS controlled CSS and DOM manipulation, there isn't actually a scrollTo() invocation. This puts it all in the same render cycle.
Try using a button instead of the div and use setfocus() when the specific item is activated. The browser will automatically scroll to make the focused button always visible. You can use CSS to make the button look exactly like the div.
I have a long jQuery mobile page and would like to scroll to an element halfway down this page after the page loads.
So far I've tried a few things, the most successful being:
jQuery(document).bind("mobileinit", function() {
var target;
// if there's an element with id 'current_user'
if ($("#current_user").length > 0) {
// find this element's offset position
target = $("#current_user").get(0).offsetTop;
// scroll the page to that position
return $.mobile.silentScroll(target);
}
});
This works but then the page position is reset when the DOM is fully loaded. Can anyone suggest a better approach?
Thanks
A bit late, but I think I have a reliable solution with no need for setTimeout(). After a quick look into the code, it seems that JQM 1.2.0 issues a silentScroll(0) on window.load for chromeless viewport on iOS. See jquery.mobile-1.2.0.js, line 9145:
// window load event
// hide iOS browser chrome on load
$window.load( $.mobile.silentScroll );
What happens is that this conflicts with applicative calls to silentScroll(). Called too early, the framework scrolls back to top. Called too late, the UI flashes.
The solution is to bind a one-shot handler to the 'silentscroll' event that calls window.scrollTo() directly (silentScroll() is little more than an asynchronous window.scrollTo() anyway). That way, we capture the first JQM-issued silentScroll(0) and scroll to our position immediately.
For example, here is the code I use for deep linking to named elements (be sure to disable ajax load on inbound links with data-ajax="false"). Known anchor names are #unread and #p<ID>. The header is fixed and uses the #header ID.
$(document).bind('pageshow',function(e) {
var $anchor;
console.log("location.hash="+location.hash);
if (location.hash == "#unread" || location.hash.substr(0,2) == "#p") {
// Use anchor name as ID for the element to scroll to.
$anchor = $(location.hash);
}
if ($anchor) {
// Get y pos of anchor element.
var pos = $anchor.offset().top;
// Our header is fixed so offset pos by height.
pos -= $('#header').outerHeight();
// Don't use silentScroll() as it interferes with the automatic
// silentScroll(0) call done by JQM on page load. Instead, register
// a one-shot 'silentscroll' handler that performs a plain
// window.scrollTo() afterward.
$(document).bind('silentscroll',function(e,data) {
$(this).unbind(e);
window.scrollTo(0, pos);
});
}
});
No more UI flashes, and it seems to work reliably.
The event you're looking for is "pageshow".
I was digging a lot this issue, also at jQuery mobile official forum.
Currently it seems that there is no solution (at least for me).
I tried different events (mobileinit, pageshow) and different functions (silentscroll, scrolltop) as suggested above, but, as a result, I always have page scrolled until all images and html is finished loading, when page is scrolled to top again!
Partial and not really efficient solution is using a timer as suggested in comment to sgliser's answer; unfortunately with a timeout is difficult to know when page will be fully loaded and if scroll happened before that, it will scroll back to top at the end of load, while if it happens too long after page has fully loaded, the user is already scrolling page manually, and further automated scroll will create confusion.
Additionally, would be useful to have silentscroll or other function to address a specific id or class and not plain pixels, because with different browsers, resolutions and devices it may give different and not correct positioning of the scroll.
Hope someone will find a smarter and more efficient solution than this.
I need to prevent the automatic scroll-to behavior in the browser when using link.html#idX and <div id="idX"/>.
The problem I am trying to solve is where I'm trying to do a custom scroll-to functionality on page load by detecting the anchor in the url, but so far have not been able to prevent the automatic scrolling functionality (specifically in Firefox).
Any ideas? I have tried preventDefault() on the $(window).load() handler, which did not seem to work.
Let me reiterate this is for links that are not clicked within the page that scrolls; it is for links that scroll on page load. Think of clicking on a link from another website with an #anchor in the link. What prevents that autoscroll to the id?
Everyone understand I'm not looking for a workaround; I need to know if (and how) it's possible to prevent autoscrolling to #anchors on page load.
NOTE
This isn't really an answer to the question, just a simple race-condition-style kluge.
Use jQuery's scrollTo plugin to scroll back to the top of the page, then reanimate the scroll using something custom. If the browser/computer is quick enough, there's no "flash" on the page.
I feel dirty just suggesting this...
$(document).ready(function(){
// fix the url#id scrollto "effect" (that can't be
// aborted apparently in FF), by scrolling back
// to the top of the page.
$.scrollTo('body',0);
otherAnimateStuffHappensNow();
});
Credit goes to wombleton for pointing it out. Thanks!
This seems the only option I can see with ids:
$(document).ready(function() {
$.scrollTo('0px');
});
It doesn't automatically scroll to classes.
So if you identify your divs with unique classes you will lose a bit of speed with looking up elements but gain the behaviour you're after.
(Thanks, by the way, for pointing out the scroll-to-id feature! Never knew it existed.)
EDIT:
I know this is an old thread but i found something without the need to scroll. Run this first before any other scripts. It puts an anchor before the first element on the page that prevents the scroll because it is on top of the page.
function getAnchor(sUrl)
{
if( typeof sUrl == 'string' )
{
var i = sUrl.indexOf( '#' );
if( i >= 0 )
{ return sUrl.substr( i+1 ).replace(/ /g, ''); }
}
return '';
};
var s = getAnchor(window.location.href);
if( s.length > 0 )
{ $('<a name="'+s+'"/>').insertBefore($('body').first()); }
Cheers!
Erwin Haantjes
Scroll first to top (fast, no effects pls), and then call your scroll function. (I know its not so pretty)
or just use a prefix
This worked well for me:
1- put this on your css file
a[name] { position: absolute; top: 0px }
2- put this on your document.ready bind right before you start animating (if you're animating at all)
$("a[name]").css("position","relative");
Might need tweaking depending on your stylesheet/code but you get the idea.
Credit to: http://cssbeauty.com/skillshare/discussion/1882/disable-anchor-jump/