我想在用户切换“平板电脑模式”时动态更改为触摸友好的布局,如果他们关闭平板电脑模式,则切换回我们的“桌面”布局。
这需要(1)在JavaScript中检测平板电脑模式(2)检测平板电脑模式的开/关变化。
我更喜欢纯JavaScript和DOM(不是jQuery,Modernizr等)。
原因:我们有一个高密度(类似桌面)的用户界面,我们不能轻易改变。我希望在“平板电脑模式”下添加间距以使触控更友好。这与Windows 10任务栏在平板电脑模式下在图标之间添加额外填充相同(可能是其他Windows 10应用程序会以这种方式运行?!)
编辑:我做了一些视口研究,因为看起来零宽度滚动条是检测平板电脑模式(或Metro)的技巧。 http://pastebin.com/ExPX7JgL
平板电脑模式:Edge中的滚动条宽度为0。不是平板电脑模式:Edge中的滚动条宽度不为零。
使用纯JavaScript代码here。
这适用于Windows 10上的Edge(IE12),但不适用于Internet Explorer 11。
检测平板电脑模式已发生变化的可靠方法是here。
请注意,由于其他原因(iOS,Android,Windows Phone,Safari OSX或-ms-overflow-style: none
等原因),滚动条宽度可能为零。 Modernizr 3具有hiddenscrollbar特征检测功能,可检测是否使用了零宽度滚动条。
请注意,如果您使用触摸而不是使用鼠标/触摸板,则边缘滚动条的行为和显示方式会有所不同。 (如果您滚动然后快速更改为平板电脑模式,您甚至可以同时显示精简和旧式滚动条样式)!请注意,我怀疑边缘调试器会干扰滚动条检测(但可能是因为我在触摸和触摸板之间切换)。
我会阻止你做那样的平台特定的事情。 即使在Windows 10应用程序中,一般设计指南也是根据视图大小更改UI,并根据输入设备更改交互,而不是实际视图。
你应该使用pointer events代替。
这是一个W3C标准,可以从手写笔/鼠标/触摸接收事件。它有一个pointer-type属性,您可以用来检测哪一个与您的网站进行交互。 (在Firefox / Opera / IE中支持,很快Chrome)
使用依赖于滚动条粗细的calc()似乎可行,但在检测滚动条大小调整时不可靠。只需将其添加到此处以防止该想法有所帮助。
.metrics-edge-outer {
position: absolute;
height: 50px;
width: 50px;
}
.metrics-edge-1,
.metrics-edge-2 {
width: 100px; /* cause bottom scrollbar */
}
.metrics-edge-1 {
height: calc(50px + 50px - 100% - 2px);
/* bistable - if scrollbar has thickness then once scrollbar shows then it stays showing - when scrollbar thickness goes to zero due to tablet mode then height shrinks to 48px (and scroll event happens) */
}
.metrics-edge-2 {
height: calc(200% - 50px + 2px);
/* bistable - if scrollbar has zero thickness then once area is scrollable it stays is scrollable - if scrollbar thickness goes to 17px due to non-tablet mode then height goes to less than 48px (and scroll event happens) */
}
和代码一起使用(甚至没有语法检查,因为从框架编辑):
var tabletModeNode;
function detectTabletMode() { // Also see http://www.backalleycoder.com/resize-demo.html
var innerDiv = core.div({
className: (getScrollbarThickness() > 0) ? 'metrics-edge-1' : 'metrics-edge-2'
});
tabletModeNode = core.div({
className: 'metrics-edge-outer',
tabIndex: -1
}, [innerDiv]);
this.node.appendChild(tabletModeNode);
redetectTabletMode();
tabletModeNode.addEventListener('scroll', function() {
if (!tabletModeNode.scrollTop) {
alert('on tablet mode');
redetectTabletMode();
}
});
}
var tabletTimer;
function redetectTabletMode: function() {
tabletModeNode.style.overflow = 'scroll';
tabletModeNode.scrollTop = 1;
clearTimeout(tabletTimer);
tabletTimer = setTimeout(function() { // Wait until after CSS rules have run (and inner div is bigger than outer div)
tabletModeNode.style.overflow = 'auto';
}, 1000);
}