Javascript scroll and iphone / ipad - javascript

I'm making a mobile version of my website (programmetv.net) and i have a problem with javascript scroll event who not work on ipad same on a pc.
You can see my mobile version on http://www.programmetv.net/ipad/index.php?date=20130210
If you test with a pc, the channels stay in the left of the screen, but if you test with an ipad (or iphone), you can see my javascript do not work correctly. The channels become invisible and if you stop to scroll they become visible.
There is my javascript to to this :
<script language="JavaScript">
document.onscroll = scrollIt;
function scrollIt() {
var node = document.getElementById("chaines");
var XX = 0;
var YY = 0;
var posit = (window.pageXOffset < (XX-YY))
? XX : window.pageXOffset + YY;
node.style.left = posit + "px";
}
</script>
I would like help to make ipad version of my javascript who work like on a pc (firefox).

Related

Mobile Safari parallax scroll not working

I have developed this JavaScript code to do parallax scrolling on an image at the top of the page. The code works flawlessly in Chrome, FF, IE, Opera and Safari, on desktop. When I test it on Safari on my iPad though, it ignores the parallax scrolling all-together, and just scrolls normally past the image. I have tried to debug from my iPad, but it doesn't seem to be working because I have a Windows computer. Does anyone see any reason why this wouldn't work on mobile Safari? Note: I also tried implementing background-position-x and background-position-y from another StackOverflow post, but it didn't help at all.
JS Code:
var getHeight = window.innerHeight;
if (getHeight > 750) {
$('#bannerImage').each(function () {
var $obj = $(this);
$(window).scroll(function () {
var yPos = -($(window).scrollTop() / 5);
var xPos = -($(window).scrollLeft() / 5);
var bgpos = yPos + 'px';
var bgposx = xPos + 'px';
var coordinates = bgposx + ' ' + bgpos;
$("div#slideshow div img").css('background-position', coordinates);
$("div#slideshow div img").css('background-position-x', bgposx);
$("div#slideshow div img").css('background-position-y', bgpos);
});
});
}
});
HTML:
<div class="BannerContainer">
<div class="vibeBannerRotator">
<div id="bannerImage">
<div id="slideshow">
<div id="imgContents_1">
<img style="background-image: url('/Images/ssie_images/SSIE-Header01.jpg'); background-repeat: no-repeat; background-size: 100%;">
</div>
</div>
</div>
</div>
</div>
After reviewing my code some more, I have found that this line of code was stopping the JavaScript from executing : var getHeight = window.innerHeight;
if (getHeight > 750). I was testing this on my iPad in portrait mode, and while the screen height is technically 768px, the URL bar & top menu account for about 44px, thus the conditional 'IF' block was returning false, and the code wasn't executing. After dropping the number down to 600, I have tested again and all seems well.
The problem is that Mobile Safari doesn't execute code while scrolling.
I figured this out when I made a JavaScript game that runs on Mobile Safari. But if I swipe, it scrolls the page, periodically stopping the game.
Another example: Animated GIFs stop animating while you scroll.
You can't get around that, unfortunately.

Javascript positioning not working in Chrome or Safari

I have a script going in Javascript, the purpose of which is to make an image stay centered in the window when the window is smaller than the image. It just moves the image to the left by half the difference between the image width and the window width so that the center of the image is always the center of the screen. When the window is not smaller than the image, this left offset is set to zero. And it works perfectly, if I'm in IE or Firefox. On the webkit browsers, it doesn't ever go to zero, creating an effect akin to float:right when the window is wider than the image. Here's the code:
setTimeout(slideImageWidth, 1);
function slideImageWidth() {
var slideWidth = window.getComputedStyle(document.getElementById("slide-image")).width,
windowWidth = window.innerWidth,
slide = document.getElementById("slide-image"),
slideWidth = window.getComputedStyle(slide).width;
if (windowWidth < (slideWidth.replace("px", "") + 1) && slide.style.display !== "none") {
slide.style.left = ((((-slideWidth.replace("px", "") + windowWidth)) / 2) + "px");
}
else {
slide.style.left = 0;
setTimeout(slideImageWidth, 1);
};
I tried putting slide.style.left = 0 before the if and just letting the loop take care of it in the next millisecond, but that didn't work either. I've also tried both placements with:
slide.style.left = "0px";
slide.style.left = 0 + "px";
slide.style.left = "0" + "px";
slide.style.left = 0px;
none of which worked in Chrome or Safari, but all but the last of which worked in Firefox and IE.
When I use alert(slide.style.left) when the window is wider than the image, a positive value is returned in Chrome and Safari, unlike the 0 from Firefox and IE, which tells me that the 0 value is never being written to slide.style.left. Yet, I know that I can modify slide.style.left because it still positions itself based on the equation.
Why does this code not work with the webkit browsers, and how can I fix it?
First, the things which I think are accidental typos:
1) Your code references something called "slide1Width", which is defined nowhere.
2) Your code references something called "slide1", which is defined nowhere.
3) You don't have the right number of close brackets, and the last bracket inexplicably has a semicolon after it.
Second, the most obvious error that isn't causing your specific problem:
(slideWidth.replace("px", "") + 1)
This expression is not what you want. If slideWidth is "440px", the replace() call gives you "440", and ("440" + 1) is the string "4441". I don't think that's what you mean to do here.
Third, and finally, what I believe is the cause of the actual bug you're asking about: timing. If you open up the dev tools and manually run slideImageWidth() on a wide window after it has loaded and failed to center itself, the image will in fact jump to the center, even on Chrome. Why doesn't it do it on page load? Here:
window.getComputedStyle(slide).width
That expression returns "0px" right when the page is first loaded. If you wait until the image is done loading, you'll be able to get an actual width for it, in which case you can do the calculations you want. (Or, presumably, you could set the width yourself via styling.) It seems that IE is getting the image loaded and flowed before running the script, whereas Chrome is not.
Is there a reason you want to use setTimeout instead of a resize event? What about something like this:
window.onresize = function(event) {
setSlidePosition();
};
function setSlidePosition() {
var slideLeft = (document.getElementById("slide-image").style.left.indexOf('px') != -1 ) ? document.getElementById("slide-image").style.left : '0px';
var numLeft = slideLeft.replace('px','');
console.log(numLeft);
var element = document.getElementById("slide-image")
if(element.width > window.innerWidth) {
var newLeft = (element.width - window.innerWidth) / 2 * -1 + "px";
document.getElementById("slide-image").style.left = newLeft;
} else {
document.getElementById("slide-image").style.left = "0px";
}
};
setSlidePosition();
http://jsfiddle.net/4qomq7tb/45/
Seems to behave the same in chrome and FF at least. This doesn't specifically answer the question relating relating to your code, though :/

Scroll a page with touch events

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.

offsettop & clientHeight in firefox

I'm updating a web page from being supported by I.E. to code that works in Firefox.
I have a section of code that positions some tables on the page in certain locations. It works in IE, but it seems that .clientHeight .offsetTop .style.posTop and .style.posLeft do not work in firefox. are there alternatives for the Firefox browser?
Here's the piece of code that I'm looking at:
var tableHeight = table1.clientHeight;
var yLocation = table2.offsetTop - tableHeight / 4;
table3.style.posTop = Math.max(table2.offsetTop + 2);
table3.style.posLeft = + table2.offsetLeft + 80;

Slow Javascript touch events on Android

I'm trying to write a simple html based drawing application (standalone simplified code attached bellow). I've tested this on the following devices:
iPad 1 and 2: Works great
ASUS T101 running Windows: Works great
Samsung Galaxy Tab: Extremely slow and patchy -- unusable.
Lenovo IdeaPad K1: Extremely slow and patchy -- unusable.
Asus Transformer Prime: Noticeable lag compare with the iPad -- close to usable.
The Asus tablet is running ICS, the other android tablets are running 3.1 and 3.2. I tested using the stock Android browser. I also tried the Android Chrome Beta, but that was even worse.
Here's a video which demonstrates the issue: http://www.youtube.com/watch?v=Wlh94FBNVEQ
My questions is why are the Android tablets so slow? Am I doing something wrong or is it an inherit problem with Android OS or browser, or is there anything I can do about it in my code?
multi.html:
<html>
<body>
<style media="screen">
canvas { border: 1px solid #CCC; }
</style>
<canvas style="" id="draw" height="450" width="922"></canvas>
<script class="jsbin" src="jquery.js"></script>
<script src="multi.js"></script>
</body>
</html>
multi.js:
var CanvasDrawr = function(options) {
// grab canvas element
var canvas = document.getElementById(options.id),
ctxt = canvas.getContext("2d");
canvas.style.width = '100%'
canvas.width = canvas.offsetWidth;
canvas.style.width = '';
// set props from options, but the defaults are for the cool kids
ctxt.lineWidth = options.size || Math.ceil(Math.random() * 35);
ctxt.lineCap = options.lineCap || "round";
ctxt.pX = undefined;
ctxt.pY = undefined;
var lines = [,,];
var offset = $(canvas).offset();
var eventCount = 0;
var self = {
// Bind click events
init: function() {
// Set pX and pY from first click
canvas.addEventListener('touchstart', self.preDraw, false);
canvas.addEventListener('touchmove', self.draw, false);
},
preDraw: function(event) {
$.each(event.touches, function(i, touch) {
var id = touch.identifier;
lines[id] = { x : this.pageX - offset.left,
y : this.pageY - offset.top,
color : 'black'
};
});
event.preventDefault();
},
draw: function(event) {
var e = event, hmm = {};
eventCount += 1;
$.each(event.touches, function(i, touch) {
var id = touch.identifier,
moveX = this.pageX - offset.left - lines[id].x,
moveY = this.pageY - offset.top - lines[id].y;
var ret = self.move(id, moveX, moveY);
lines[id].x = ret.x;
lines[id].y = ret.y;
});
event.preventDefault();
},
move: function(i, changeX, changeY) {
ctxt.strokeStyle = lines[i].color;
ctxt.beginPath();
ctxt.moveTo(lines[i].x, lines[i].y);
ctxt.lineTo(lines[i].x + changeX, lines[i].y + changeY);
ctxt.stroke();
ctxt.closePath();
return { x: lines[i].x + changeX, y: lines[i].y + changeY };
},
};
return self.init();
};
$(function(){
var drawr = new CanvasDrawr({ id: "draw", size: 5 });
});
Looking at your code, you should do some optimizing. Right off the bat, never use jQuery's $.each() to do loops. Also, every time you poll the left, top, width or height of something, you're causing the browser to stop what it's doing, repaint the entire screen, and fetch you the most accurate values. Store these values in javascript variables instead. Use google chrome's timeline feature to find and eliminate unecessary paints and reflows. Here are some helpful links:
Nicholas C. Zakas Gives You Some Tips on avoiding Reflows.
http://oreilly.com/server-administration/excerpts/even-faster-websites/writing-efficient-javascript.html
Here is Zakas giving his presentation to Google programmers:
http://www.youtube.com/watch?v=mHtdZgou0qU
Paul Irish Speeds up a slow JavaScript in front of your eyes:
http://www.youtube.com/watch?v=Vp524yo0p44
Please note, at the time of that video, the timeline was a beta feature in Chrome. It's now standard in Chrome 20. If you don't see it, update your Chrome.
Unfortunately... Even with all these optimizations... as of 2012 ...
MOST ANDROID DEVICES ARE STILL SLOW :-(
The touch events don't fire as rapidly as they do in Apple devices because Apple devices just have better hardware than most devices running Android's OS. There are fast Android tablets and phones out there, but they usually cost as much as much as the Apple devices--probably because they have similar hardware specs. Apple devices have special floating-point math chips and graphics chips in addition to the main CPU. Many Android devices do not contain those extra chips, instead they have virtual floating-point math chips.
The only thing you can do to accommodate slower Android devices is to detect them and gracefully degrade the user experience. For example, I created a draggable product carousel. For Androids, I eliminate the drag option and add clickable scroll arrows that move the carousel to the left or right a fixed set of pixels at a time.
The only way to really know where and why your code is underperforming is to profile it.
Chrome Mobile lets you connect to the WebKit inspector from your desktop, giving you access to the fantastic debugging tools you're used to in Chrome's Developer Tools.
Once you're connected to Chrome Mobile, profile your script and see what functions are chewing up CPU time. Then you'll be able to start figuring out how to optimize those functions.

Categories

Resources