I have an iFrame. If a user zooms in or uses high magnification due to bad eyesight, I want a horizontal scroll bar to appear so that the user can scroll left to right within the iFrame. This part is easy and not an issue. The problem I've found is that the scroll bar appears at the bottom of the iFrame, which, if zoomed in enough to need it, would require the user to scroll very far down from the actual content to use it, which isn't user friendly.
What I want is for a scroll bar to be visible at the bottom of the visible window that is linked to the main scroll bar, and would be a bonus if it disappears if the user does scroll down enough to see the main scroll bar.
I should reiterate that this is inside an iFrame where the content is cross-domain. I can edit the content in the iFrame but it would be a fairly large task to do that, whereas editing the main window is relatively simple, so would be nice if all the work required could be done in there instead.
Another option you have is to control the scroll with the mouse wheel, see example https://jsfiddle.net/DIRTY_SMITH/5gs8pojm/
(function() {
function scrollHorizontally(e) {
e = window.event || e;
var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
document.documentElement.scrollLeft -= (delta*40); // Multiplied by 40
document.body.scrollLeft -= (delta*40); // Multiplied by 40
e.preventDefault();
}
if (window.addEventListener) {
// IE9, Chrome, Safari, Opera
window.addEventListener("mousewheel", scrollHorizontally, false);
// Firefox
window.addEventListener("DOMMouseScroll", scrollHorizontally, false);
} else {
// IE 6/7/8
window.attachEvent("onmousewheel", scrollHorizontally);
}
})();
Related
In short:
In iOS Safari, window.scrollTo method doesn't do anything if called from orientationchange event handler. It seems like a certain amount of time (500-1000ms) must pass before you can modify scroll position after orientation change.
Is there a workaround to change scroll position immediately and avoid the problem when user can see old scroll position for a moment after orientation change?
Detailed problem description:
I need to implement the following feature for mobile browsers:
When the user switches to landscape mode, he should see fullscreen video. When he switches back to portrait, he should be returned to exact same place where he left off.
The second part is the problem. Both iOS and Android will keep scroll position if you switch orientation back and forth, but only if you dont scroll the screen and dont make any adjustments to DOM. So if you just switch from portrait to landscape and back, everything works as expected. If you switch from portrait to landscape, adjust scroll position even by 1 pixel or make any changes to DOM, you will return to a different scroll position.
So I'm trying to pragmatically restore scroll position once the user returns to portrait orientation. Here's the simplified code I use:
var scrollPosition;
var savedScrollPosition;
window.addEventListener('scroll', function() {
scrollPosition = window.scrollY;
});
window.addEventListener('orientationchange', function(event) {
if (Math.abs(window.orientation) === 90) {
// This line will correctly save last scroll position for portrait orientation
savedScrollPosition = scrollPosition;
} else {
// This line will correctly try to restore previously saved scroll position
window.scrollTo(0, savedScrollPosition);
}
});
This works on android, but on iOS it doesn't. The problem is, window.scrollTo just doesn't seem to do anything until the certain time after orientation change has passed.
So if I change
window.scrollTo(0, savedScrollPosition);
to
setTimeout(function() {
window.scrollTo(0, savedScrollPosition);
}, 1000);
it works on iOS, but the user can see wrong portion of the page for a few moments, which leads to a poor user experience.
I was hoping that somebody knows a way to change scroll position on iOS immediately after orientationchage event.
Thank you.
In the end, I was forced to go with the following code:
var scrollPosition;
var savedScrollPosition;
window.addEventListener('scroll', function() {
scrollPosition = window.scrollY;
});
window.addEventListener('orientationchange', function(event) {
if (Math.abs(window.orientation) === 90) {
savedScrollPosition = scrollPosition;
} else {
if (isIOS()) {
var retryScroll = setInterval(function () {
if (window.scrollX === 0 && window.scrollY == savedScrollPosition) {
clearInterval(retryScroll);
} else {
window.scrollTo(0, savedScrollPosition);
}
}, 10 );
} else {
window.scrollTo(0, savedScrollPosition);
}
}
});
The user will see a small visual glitch, but it's still the best solution.
I'm creating a web-app for iOS Safari and have run into a slight hurdle.
My web-app only takes up 1024x768 of screen real estate and therefore does not need scrolling, but it does need to be able to zoom (it's a PDF annotator).
I have used a plugin called iNoBounce (https://github.com/lazd/iNoBounce/) which successfully removes scrolling from the page by firing an evt.preventDefault() on the touchmove/touchstart events. This is great.
What this does though, is remove zoom events as well as scroll events. Is there a way to remove scrolling/elastic bouncing but to retain zoom on iOS safari?
Many thanks
I managed to solve this issue by listening to some values on the touch event object, specifically changedTouches.length and scale.
First I set a global variable for zoomLevel at the top of the document var zoomLevel = 1
Next, I replaced evt.preventDefault() in iNoBounce with:
if(evt.changedTouches.length === 1 && zoomLevel <= 1){
evt.preventDefault();
}
if(evt.changedTouches.length > 1){
zoomLevel = evt.scale;
}
This looks at how many fingers are being used and if the page scale is not 100%, then acts accordingly.
I have a website page and I've added to the body of the page touch events.
More exactly for swipe right and swipe left. Since the event listener is added to the body of the page and I have added event.preventDefault(); i can't scroll the page any more.
How can i scroll the page in the browser ?
P.S. The code is pure javascript / library agnostic.
Edit #1. This site viewed in mobile seems to do it http://swipejs.com/ . It slides the tabs right to left and back as well as scroll the website. I just can't seen in the code how :(
Use iscroll plugin. it's help to you.
see example : http://cubiq.org/dropbox/iscroll4/examples/simple/
Unfortunately there is no easy answer. The best way is to build smart gesture recognizers. Or use something like this (for Safari Mobile):
http://mud.mitplw.com/JSGestureRecognizer/#single-gesture
You will notice that when you are touching a gesture recognizer, there is no scrolling. However, you could make the callback of a recognizer scroll the page.
Wondering why it only says it supports Safari mobile? That's because Safari mobile has its own set of touch events. However, you can use it as a start and try to add support for other platforms.
I have the same problem that swiping without "preventDefault()". Because I want to achieve a pulltorefresh's effect, I can only prevent the pulldown event but not pullup. The code like this:
function touchBindMove(evt){
//evt.preventDefault();
try{
var deviceHeight = window.innerHeight;
var touch = evt.touches[0]; //获取第一个触点
var x = Number(touch.pageX); //页面触点X坐标
var y = Number(touch.pageY); //页面触点Y坐标
//记录触点初始位置
if((y - offsetStart) > 0 && document.body.scrollTop == 0){
evt.preventDefault();
var page = document.getElementsByClassName('tweet-page')[0];
var rate = 0;
end = x;
offsetEnd = y;
rate = (offsetEnd - offsetStart) / (2 * deviceHeight);
//tool.print(rate);
easing.pullMotion(page, rate);
}
}catch(e){
alert(e.message);
}
}
"y - offsetStart" judges whether the event is pulldown and "document.body.scrollTop == 0" judges the scrollbar is in the middle or not.
Maybe it can help you a little bit.
...the reason I ask is that Safari has a bug in its implementation of scroll() that is breaking my UI.
Imagine a page:
<body>
<div id="huge" style="width: 4000px; height: 4000px;"></div>
</body>
...so that you get both horizontal and vertical scrollbars. Now, normally when you press the scrollbar, the page scrolls (vertically). For the purposes of our fancy UI we don't want that to happen, so we squash the keyDown event:
window.onkeydown = function(e) {
if(e.keyCode == 32)
{
return false;
}
};
This works great...unless we decide that instead of preventing scrolling altogether, we want our own, custom scrolling behavior:
window.onkeydown = function(e) {
if(e.keyCode == 32)
{
window.scroll(foo, bar); // Causes odd behavior in Safari
return false;
}
};
In other browsers (Chrome, Firefox), this will instantaneously move the window's scroll position to the desired coordinates. But in Safari this causes the window to animate to the desired scroll position, similar to the scrolling animation that takes place if you press the space bar.
Note that if you trigger this scroll off of any key OTHER than the space bar, the animation does not take place; the window scrolls instantly as in other browsers.
If you happen to be scrolling, say, 1000 pixels or more, then the animated scroll can induce some serious discomfort.
I'm scratching my head trying to find a way around this. I suspect that there isn't one, but I'm hoping some God of Javascript here can suggest something. I'd really like to be able to use the space bar for this command.
If you know where in the document you want to scroll to then you can simply use named anchors. Setting document.location to the anchor (e.g. #top, #div50 or whatever) should be very reliable.
Use document.documentElement.scrollTop = ... (and document.body in some browsers).
I have a very wide website, intentionally designed to have no vertical scrolling but a lot of horizontal.
Scrolling horizontally is usually a pain to users so was wondering if there was some way of using the middle mouse or other scrolling habits (eg. page up/down, up/down arrows, middle mouse click/drag) to scroll horizontally instead of vertically.
Edit: The main reason for requiring horizontal scrolling is because the layout/approach is a left to right graphical/interactive timeline. I've since found some examples;
This one with MooTools: http://www.tinkainteractive.com.au/ and a few other examples I found at http://naldzgraphics.net/inspirations/40-examples-of-horizontal-scrolling-websites/
You can add your own event listener
document.onmousewheel = myScrollFunction
Scrolling can be done by
window.scrollBy(x, y)
Where x is the horizontal scrolling offset and y the vertical scrolling offset.
So you might just call this function in your event listener. You may have to stop bubbling with event.stopPropagation and prevent browser default behaviour with event.preventDefault so that the original scrolling behaviour doesn't get applied anymore.
Edit: I was curious about this so I implemented something :-)
function onScroll(event) {
// delta is +120 when scrolling up, -120 when scrolling down
var delta = event.detail ? event.detail * (-120) : event.wheelDelta
// set own scrolling offset, take inverted sign from delta (scroll down should scroll right,
// not left and vice versa
var scrollOffset = 10 * (delta / -120);
// Scroll it
window.scrollBy(scrollOffset, 0);
// Not sure if the following two are necessary, you may have to evaluate this
event.preventDefault;
event.stopPropagation;
}
// The not so funny part... fin the right event for every browser
var mousewheelevt=(/Firefox/i.test(navigator.userAgent)) ? "DOMMouseScroll" : "mousewheel";
if (document.attachEvent)
document.attachEvent("on"+mousewheelevt, onScroll);
else if (document.addEventListener)
document.addEventListener(mousewheelevt, onScroll, false);
This works in Firefox 3.5 and Opera 10, however not in IE8. But that would be your part now... ;-)
I wouldn't change this behaviour. It would be very unexpected to the user. Maybe it makes sense to cover the symptom and re-layout your website to switch to a more vertical centered approach?
Still you can do loads of event-handling stuff with java-script, but as said I would rethink the layout.