jQuery 以编程方式更改 scrollTop 后,固定位置按钮上的移动 Safari 错误...?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8752220/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mobile Safari bug on fixed positioned button after scrollTop programmatically changed...?
提问by tsdexter
I'm just about done a webpage but there is one bug in Mobile Safari (iPhone and iPad iOS 5.0.1) with two buttons that are fixed to the upper and lower right corners..
我刚刚完成了一个网页,但 Mobile Safari(iPhone 和 iPad iOS 5.0.1)中有一个错误,两个按钮固定在右上角和右下角。
The buttons are not faded in until after clicking submit on a textbox which opens up to the rest of the page... After the rest of the page is loaded and the buttons are faded in you can click on either of them and they both work...
直到在打开到页面其余部分的文本框上单击提交后,按钮才会淡入...加载页面的其余部分并且按钮淡入后,您可以单击其中任何一个,它们都可以工作...
However, clicking them causes a programmatic scroll and after that scroll is complete you can no longer click on either of the buttons until you physically scroll the page with your finger even just a tiny one pixel scroll...
但是,单击它们会导致程序化滚动,在滚动完成后,您将无法再单击任何一个按钮,直到您用手指物理滚动页面,即使只是很小的一个像素滚动...
What I have noticed is that after the programmatic scrolling if you tap just slightly below the TOP button you see the highlight as if you were tapping the BOTTOM button and the action of the bottom button is processed, which tells me the bug is that when scrolling programmatically the fixed position button still moves with the rest of the page and doesn't go back to it's fixed position until an actual touch scroll is performed....
我注意到的是,在编程滚动后,如果您轻按 TOP 按钮的下方,您会看到高亮显示,就像您轻按 BOTTOM 按钮一样,并且处理了底部按钮的动作,这告诉我错误在于滚动时以编程方式,固定位置按钮仍然与页面的其余部分一起移动,并且在执行实际触摸滚动之前不会返回到它的固定位置......
Does anyone know a way around this..?
有谁知道解决这个问题的方法..?
I've added a popup that shows which button was pressed so you can test it, remember after the first press of the down button (which works) trying pressing down again, it won't work, but click just below the up button and you'll see the down button actions happening....
我添加了一个弹出窗口,显示按下了哪个按钮,以便您可以对其进行测试,请记住,在第一次按下向下按钮(有效)后尝试再次按下,它将不起作用,但单击向上按钮正下方,然后你会看到向下按钮动作发生....
thanks for the help.
谢谢您的帮助。
Thomas
托马斯
(also if you can point me to where I can submit a bug to Apple that'd be good too, unless one already has been)
(另外,如果您能指出我可以向 Apple 提交错误的地方,那也很好,除非已经提交了)
EDIT: just click either of the submit arrows, you don't need to enter a wage/salary it has defaults
编辑:只需单击任一提交箭头,您无需输入默认的工资/薪水
EDIT 2: Here is a simpler example to show the same issue..
编辑 2:这是一个更简单的例子来展示同样的问题..
http://www.tsdexter.com/MobileSafariFixedPosBug.html
http://www.tsdexter.com/MobileSafariFixedPosBug.html
EDIT 3: Bug reported to Apple
编辑 3:向 Apple 报告的错误
采纳答案by Chad Smith
I got around it by adding a 101% high div then (almost) immediately removing it.
我通过添加 101% 高 div 然后(几乎)立即删除它来解决它。
Try:
尝试:
<style>
.iosfix {
height: 101%;
overflow: hidden;
}
</style>
and when you scroll:
当你滚动时:
window.scrollTo(0, _NEW_SCROLLTOP_);
$('body').append($('<div></div>').addClass('iosfix'));
setTimeout(function() {
$('.iosfix').remove();
}, 500);
It also works with jQuery.scrollTo.
它也适用于 jQuery.scrollTo。
See an example here.
请参阅此处的示例。
回答by Dominic Warren
We also encountered this bug on 2 different iPad applications, for us the best fix was to temporarily remove the fixed position from the fixed element once the animated scroll had finished, then use window.scroll with the vertical value we'd just performed the animated scroll to, then finally re-apply the position fixed style. It does cause a very minor blip as the ipad re-renders the element but its preferable to the bug.
我们还在 2 个不同的 iPad 应用程序上遇到了这个错误,对我们来说最好的解决方法是在动画滚动完成后暂时从固定元素中删除固定位置,然后使用 window.scroll 和我们刚刚执行动画的垂直值滚动到,然后最后重新应用位置固定样式。当 ipad 重新渲染元素时,它确实会导致一个非常小的光点,但它比错误更可取。
var $fixedElement = $('#fixedNavigation');
var topScrollTarget = 300;
$("html:not(:animated),body:not(:animated)").stop().animate({ scrollTop: topScrollTarget }, 500, "swing", function(evt) {
$fixedElement.css({ "position": "relative" });
window.scroll(0, topScrollTarget );
$fixedElement.css({ "position": "fixed" });
});
回答by Ed Kirk
I had multiple links on separate fixed elements (a modal popup + fixed blackout div + normal fixed toolbar) and none of these answers were working so I had a tinker about trying variations on the same theme. Like all these suggest the key is getting elements re-rendered.
我在单独的固定元素上有多个链接(模态弹出窗口 + 固定遮光 div + 普通固定工具栏),但这些答案都不起作用,所以我想在同一主题上尝试变体。就像所有这些都表明关键是重新渲染元素。
Initially I tried adding 1px to the width of fixed elements and removing it. This did cause re-rendering, but re-rendered elements became mis-aligned with non re-rendered elements - another result of this iOS bug I suspect. The answer was to simply add to the width of the body and subtract again (or set to auto), ie:
最初我尝试在固定元素的宽度上添加 1px 并将其删除。这确实导致了重新渲染,但重新渲染的元素与非重新渲染的元素未对齐 - 我怀疑这个 iOS 错误的另一个结果。答案是简单地增加身体的宽度并再次减去(或设置为自动),即:
//jQuery will calculate the current width and then +1 to this and set it
$('body').css('width', '+=1');
//Remove width css
setTimeout(function() {
$('body').css('width', '');
}, 1);
If not using jquery you will need to get the current width of body +1px to it and then set the width.
如果不使用 jquery,则需要获取 body +1px 的当前宽度,然后设置宽度。
回答by Stephane Brillant
Here is my solution if like me, none of the previous solution is working for you.
如果像我一样,这是我的解决方案,以前的解决方案都不适合您。
The trick is:
诀窍是:
- Do your scroll (Animate or scrollTo, etc.)
- Just after your scroll, position:absolute your fixed elements
- On the 'touchmove' event, restore the position:fixed
- 做你的滚动(Animate 或 scrollTo 等)
- 就在你滚动之后, position:absolute 你的固定元素
- 在 'touchmove' 事件上,恢复位置:固定
Here an example:
这里有一个例子:
$('body').animate({
scrollTop: newPos}, 1000, 'jswing', function () {
$('header').css({position:'absolute', top:newPos});
});
$(document).bind('touchmove',function(){
$('header').css({position:'fixed', top:'0px'});
});
I used the same trick for sticky footer and other floating fixed elements.
我对粘性页脚和其他浮动固定元素使用了相同的技巧。
回答by httpete
A variation of this worked for me as well. Trying to not use frameworks where I can on mobile.
这种方法的一个变体也对我有用。尽量不使用我可以在移动设备上使用的框架。
var d = document.createElement("div");
d.style.height = "101%";
d.style.overflow = "hidden";
document.body.appendChild(d);
window.scrollTo(0, scrollToM);
setTimeout(function() {
d.parentNode.removeChild(d);
}, 10);
回答by Luca De Angelis
After spending a couple of hours on this, I found a workaround: try scrolling (maybe with an animation) and then scrolling again to the same point (without animation).
This way you force the browser to delete the wrong rendering from the view.
在花了几个小时之后,我找到了一个解决方法:尝试滚动(可能有动画),然后再次滚动到同一点(没有动画)。
通过这种方式,您可以强制浏览器从视图中删除错误的渲染。
Example:
例子:
$('body, html')
.animate({scrollTop: 0})
.scrollTop(0);
回答by JDubDev
I was having the same problem with iOS5 and JQueryMobile. Fixed Header & Footer. Expandable content and suddenly i had a ghost footer that you could see but not touch. I had a bit of a problem getting a straight change position to absolute then back to work. It seemed to only work some of the time. I ended up using this.
我在 iOS5 和 JQueryMobile 上遇到了同样的问题。固定页眉和页脚。可扩展的内容,突然间我有了一个可以看到但不能触摸的幽灵页脚。我在将位置直接更改为绝对位置然后返回工作时遇到了一些问题。它似乎只在某些时候有效。我最终使用了这个。
$(myFixedFooter).css("position", "relative").hide(0, function () {
$(this).show(0).css("position", "");
});
This defiantly creates a "blip" as the footer does its thing. Hoever i found that some 98% of the time the footer stayed at the bottom of the page. All the other work arounds and tweaks i found and tried didn't always leave the footer at the bottom or they didn't solve the problem in the first place.
当页脚做它的事情时,这会挑衅地创建一个“昙花一现”。然而,我发现页脚有 98% 的时间都停留在页面底部。我发现并尝试的所有其他变通方法和调整并不总是将页脚留在底部,或者它们首先没有解决问题。
Hopefully Apple will fix soon.
希望苹果尽快修复。
回答by Cliff Harris
I discovered the exact behavior you describe in an iPhone app I'm writing. I load a bunch of HTML text with an index on the right side. After selecting an item from the menu and scrolling the text, the menu would then become unresponsive (because the landing zone had scrolled out from under it). I also saw that even a tiny scroll of the text would reenable the index menu.
我发现了您在我正在编写的 iPhone 应用程序中描述的确切行为。我加载了一堆 HTML 文本,右侧有一个索引。从菜单中选择一个项目并滚动文本后,菜单将变得无响应(因为着陆区已从其下方滚动出来)。我还看到,即使是很小的文本滚动也会重新启用索引菜单。
I created a test case and uploaded the file here (If you view this on a non-iPhone browser, make the window small vertically to see the correct behavior):
我创建了一个测试用例并在此处上传了文件(如果您在非 iPhone 浏览器上查看此文件,请将窗口垂直缩小以查看正确的行为):
http://www.misterpeachy.com/index_test.html
http://www.misterpeachy.com/index_test.html
I figured out that the index menu was scrolling with the text (even though the visible menu didn't move) after I tapped B and then tapped B again. Instead of scrolling to B (basically not moving), it scrolled to D.
我发现在我点击 B 然后再次点击 B 后,索引菜单随着文本滚动(即使可见菜单没有移动)。它没有滚动到 B(基本上不移动),而是滚动到 D。
Right now I'm stuck. I'm hoping that I can add some JavaScript code (I've never programmed in JavaScript, so that is a slight problem) that will scroll the text one pixel after I lift my finger off a menu item (and after the text has scrolled to the selected place, of course). Maybe JavaScript can detect the scroll and then add another scroll to that.
现在我被困住了。我希望我可以添加一些 JavaScript 代码(我从来没有用 JavaScript 编程过,所以这是一个小问题),在我将手指从菜单项上移开后(并且在文本滚动后),这些代码将滚动文本一个像素到选定的地方,当然)。也许 JavaScript 可以检测到滚动,然后添加另一个滚动。
回答by Romain
In case it can help someone:
如果它可以帮助某人:
I had the exact same problem, and my code looked something like this (it's a single-page webapp):
我遇到了完全相同的问题,我的代码看起来像这样(它是一个单页 web 应用程序):
window.scrollTo(0,0);
$('section.current').removeClass('current');
$(target).addClass('current');
I spent hours trying everything (101% height divs, changing the position type...), but finally the last suggestion described on Device-Bugssaved the day. In my case it was just a matter of scrolling when the divs aren't rendered:
我花了几个小时尝试一切(101% 高度 div,改变位置类型......),但最后在Device-Bugs上描述的最后一个建议挽救了这一天。在我的情况下,这只是在未呈现 div 时滚动的问题:
$('section.current').removeClass('current');
window.scrollTo(0,0);
$(target).addClass('current');
回答by mckamey
Another variation of a solution is to increase the size of the document width by 1px and then immediately undo it. This has the advantage of not creating any more elements and there isn't any flicker that I've experienced.
解决方案的另一个变体是将文档宽度的大小增加 1px,然后立即撤消它。这具有不创建更多元素的优点,并且没有我经历过的任何闪烁。