固定位置div在页面上冻结(iPad)
我有一个asp.net网站,我正在建立一个支持ipad的网站。当我关注一个输入元素并弹出键盘时,位置固定的标题div(通常随页面滚动)将弹出页面,其距离相当于键盘占用的量,并在输入过程中冻结在那里。一旦将键盘放回原位,div就会弹回原位并再次正常工作。我正在iOS5上测试,所以应该支持位置:fixed固定位置div在页面上冻结(iPad),ipad,ios5,css-position,Ipad,Ios5,Css Position,我有一个asp.net网站,我正在建立一个支持ipad的网站。当我关注一个输入元素并弹出键盘时,位置固定的标题div(通常随页面滚动)将弹出页面,其距离相当于键盘占用的量,并在输入过程中冻结在那里。一旦将键盘放回原位,div就会弹回原位并再次正常工作。我正在iOS5上测试,所以应该支持位置:fixed 这是一个已知的问题吗?以前有没有人遇到过这个问题并处理过?我似乎找不到这方面的任何信息。在iOS5/iOS6/iOS7上,固定定位被破坏 编辑3:有关iOS8,请参阅此答案末尾附近的工作修复程序链
这是一个已知的问题吗?以前有没有人遇到过这个问题并处理过?我似乎找不到这方面的任何信息。在iOS5/iOS6/iOS7上,固定定位被破坏 编辑3:有关iOS8,请参阅此答案末尾附近的工作修复程序链接 位置:当以下任一情况发生时,固定断开: a) 页面被缩放 或 b) 键盘显示在iPad/iPhone上(由于输入获得焦点) 您可以通过打开链接并缩放,或提供输入焦点,自己查看bug。您可以自己编辑该文件 关于错误(a)和(b)的注释:
top的固定div:0px;左:0px当输入获得焦点且键盘显示时,代码>将显示在错误的位置(屏幕顶部上方或下方)
top:
更改(例如,在0px和1px之间切换),您可以看到固定div移动了一个像素,但它仍然位于错误的位置位置:固定
仍然存在相同的问题-可能是出于设计
编辑3:(b)的工作解决方案是,当输入获得焦点时,将标题更改为绝对位置,然后在页面滚动事件中设置标题顶部。此解决方案:
- 当输入未聚焦时使用固定定位(使用window.onscroll会产生可怕的抖动)
- 不允许收缩缩放(避免上面的错误(a))
- 一旦输入获得焦点,使用绝对定位和window.pageYOffset(以便正确定位标题)
- 如果在输入具有焦点时滚动,则将style.top设置为等于pageYOffset(即使在iOS8上,由于onscroll事件延迟,标题也会有点抖动)李>
- 如果在iOS8上的应用程序中使用UIWebView,或者根据我的需要使用,我发现使用绝对定位标题、滚动前隐藏标题和滚动完成时显示标题更容易(我需要相同的代码来支持iOS4和Android)
出于我的目的,我在
事件中隐藏标题,然后在touchstart
或touchend
事件中再次显示标题(加上一些定时器以提高响应能力/减少闪烁)。它闪烁着,但这是我能找到的最好的折衷方案。可以使用scroll
事件检测滚动的开始(jQuery会这样做),但我发现touchmove
对我来说不起作用,因为:touchmove
- 通常,iPad在滚动前无法重新绘制(即,绝对页眉仍然被卡住-即使在滚动开始前更改了
)top
- 当一个输入元素获得焦点时,iPad会自动将该元素居中,但scrollstart事件不会被触发(因为如果只是
单击
输入,则不会触发touchmove)
通过使用固定和绝对定位的混合方法,可以改进iOS5上的固定报头实现:
- 用于iOS5的固定定位,直到输入获得焦点
- 当输入获得焦点(键盘显示)时,更改为iOS4绝对定位代码
- 关闭键盘后,切换回固定位置
文档
元素上注册DOMFocusOut
事件,并执行类似以下代码的操作。需要超时,因为在一个元素获得焦点和另一个元素丢失焦点之间,会触发DOMFocusOut
事件
function document_DOMFocusOut() {
clearTimeout(touchBlurTimer);
touchBlurTimer = setTimeout(function() {
if (document.activeElement == document.body) {
handleKeyboardHide();
}
}.bind(this), 400);
}
我的固定标题代码类似于:
{
setup: function() {
observe(window, 'scroll', this, 'onWinScroll');
observe(document, 'touchstart', this, 'onTouchStart');
observe(document, 'touchend', this, 'onTouchEnd');
if (isMobile) {
observe(document, 'DOMFocusOut', this, 'docBlurTouch');
} else if (isIE) {
// see http://ajaxian.com/archives/fixing-loss-of-focus-on-ie for code to go into this.docBlurIe()
observe(document, 'focusout', this, 'docBlurIe');
} else {
observe(isFirefox ? document : window, 'blur', this, 'docBlur');
}
},
onWinScroll: function() {
clearTimeout(this.scrollTimer);
this.scrolling = false;
this.rehomeAll();
},
rehomeAll: function() {
if ((isIOS5 && this.scrolling) || isIOS4 || isAndroid) {
this.useAbsolutePositioning();
} else {
this.useFixedPositioning();
}
},
// Important side effect that this event registered on document on iOs. Without it event.touches.length is incorrect for any elements in the document using the touchstart event!!!
onTouchStart: function(event) {
clearTimeout(this.scrollTimer);
if (!this.scrolling && event.touches.length == 1) {
this.scrolling = true;
this.touchStartTime = inputOrOtherKeyboardShowingElement(event.target) ? 0 : (new Date).getTime();
// Needs to be in touchStart so happens before iPad automatic scrolling to input, also not reliable using touchMove (although jQuery touch uses touchMove to unreliably detect scrolling).
this.rehomeAll();
}
},
onTouchEnd: function(event) {
clearTimeout(this.scrollTimer);
if (this.scrolling && !event.touches.length) {
var touchedDuration = (new Date).getTime() - this.touchStartTime;
// Need delay so iPad can scroll to the input before we reshow the header.
var showQuick = this.touchStartTime && touchedDuration < 400;
this.scrollTimer = setTimeout(function() {
if (this.scrolling) {
this.scrolling = false;
this.rehomeAll();
}
}.bind(this), showQuick ? 0 : 400);
}
},
// ... more code
}
这在iOS13中仍然是一个问题(当“textarea”字段中的长文本被删除时,fixed header会跳到该“textarea”字段的开头,阻碍查看),因此,我想分享一下我的快速修复方法:
因为我的页脚相当大,所以我没有使用任何JS,只是在页脚上添加了一个比固定页眉更大的z索引。看不见,想不起来。这是一个iOS错误,我暂时不讨论这个问题,但是你的建议是有效的,所以我会将这个答案标记为“更正”。JAS,是否可以提供iOS错误问题url的链接
var supportTouch = $.support.touch,
scrollEvent = "touchmove scroll",
touchStartEvent = supportTouch ? "touchstart" : "mousedown",
touchStopEvent = supportTouch ? "touchend" : "mouseup",
touchMoveEvent = supportTouch ? "touchmove" : "mousemove";
function triggerCustomEvent( obj, eventType, event ) {
var originalType = event.type;
event.type = eventType;
$.event.handle.call( obj, event );
event.type = originalType;
}
// also handles scrollstop
$.event.special.scrollstart = {
enabled: true,
setup: function() {
var thisObject = this,
$this = $( thisObject ),
scrolling,
timer;
function trigger( event, state ) {
scrolling = state;
triggerCustomEvent( thisObject, scrolling ? "scrollstart" : "scrollstop", event );
}
// iPhone triggers scroll after a small delay; use touchmove instead
$this.bind( scrollEvent, function( event ) {
if ( !$.event.special.scrollstart.enabled ) {
return;
}
if ( !scrolling ) {
trigger( event, true );
}
clearTimeout( timer );
timer = setTimeout(function() {
trigger( event, false );
}, 50 );
});
}
};