热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

移动端Web前端注解

一,布局移动端的整体布局一般来说可以分为上中下三个部分,分别为header、main、footer,其中header、footer是固定高度,分别固定在页面顶部和页面底部,而main是占据页面

一,布局

移动端的整体布局一般来说可以分为上中下三个部分,分别为 header、main、footer,其中header、footer 是固定高度,分别固定在页面顶部和页面底部,而 main 是占据页面其余位置,并且可以滚动。

页面布局如下:









根据页面滚动的位置分为两种布局,一种是滚动 body,另一种是固定 body 的高度为100%,在 main 中滚动。

第一种布局有个优点,就是页面的地址栏会随着 body 的滚动隐藏起来,并且 Android 设备中,滚动 body 会更加的流畅,如果项目中有类似需求可以考虑。

实现布局的方式如下:

body {
overflow
: auto;
}

.header,
.footer
{
position
: fixed;
left
: 0;
right
: 0;
height
: 44px;
}

.header
{
top
: 0;
}

.footer
{
bottom
: 0;
}

.main
{
height
: 100%;
padding
: 44px 0;
}

第一种情况比较适合长列表页面,整个页面除了 header 和 footer 之外都需要滚动,但很多时候,我们只希望页面的某个元素滚动,这个时候,就采取第二种布局方式。

这种页面布局有三种相对简单的实现方式:

  1. fixed 定位
  2. absolute 定位
  3. flex 定位

最容易想到的实现方式是 fixed 定位,实现方式如下:

html, body {
height
: 100%;
overflow
: hidden;
}
.header,
.footer
{
position
: fixed;
left
: 0;
right
: 0;
height
: 44px;
}


.header
{
top
: 0;
}


.footer
{
bottom
: 0;
}


.main
{
height
: 100%;
padding
: 44px 0;
box-sizing
: border-box;
}

fixed 定位实现起来简单,在大多数浏览器中也能正常显示,但是 fixed 定位在移动端会有兼容性问题,后面会提到,所以不建议这种实现方式。

absolute 定位和 fixed 定位类似,只要把 header 的 footer 的 position 改为 absolute 就可以了。

细心的小伙伴可能发现了,这里的 main 没有设置 overflow ,因为这里有一个坑,不管是absolute 定位还是 fixed 定位都一样,为了方便描述,以下只说 fixed 定位(在 absolute 定位也一样成立)。在PC端没有问题,但是在移动端,如果 main 设置了 overflow 为 true,header 会被 main 遮住,对,没有错,虽然是 fixed 定位,但是在移动端,如果 fixed 定位节点后面紧接跟着的兄弟节点是可滚动的(也就是设置了 overflow 为 true ),那么 fixed 节点会被其后的兄弟节点遮住。

这个问题解决方式有很多,既然是 fixed 定位后面紧接着可滚动的兄弟节点才会有这个坑,只要让他的条件有一个不成立就好了,有以下解决方案:

  1. 让 fixed 定位节点后面不紧接着可滚动的节点
  2. 不让 scroll 节点遮住 fixed 节点

 

第一种方方案有以下可选方法:

1. 把所有 fixed 节点放在 scroll 元素后面,即把 header 节点放在 main 节点后面





但这样显然不太符合一般人的思维习惯,代码可读性降低。

2. 使 main 不可滚动,给 main 嵌套一层可滚动的子节点










第二种方案有以下可选方法:

1. 让 scroll 节点不与 fixed 节点有重合

body {
padding
: 44px 0;
}


.main
{
padding
: 0;
}

2. 给 fixed 节点设置 z-index

.header,
.footer
{
z-index
: 8888;
}

 

简单的方式--->>>第三种实现方式,flex 布局。flex 定位在移动端兼容到了 iOS 7.1+,Android 4.4+,如果使用 autoprefixer 等工具还可以降级为旧版本的 flexbox ,可以兼容到 iOS 3.2 和 Android 2.1。而且用 flex 实现起来相对简单,在各个浏览器里表现也相对一致。实现如下:

body {
display
: flex;
flex-direction
: column;
}
.main
{
flex
: 1;
overflow
: auto;
-webkit-overflow-scrolling
: touch;
}
.header
{
height
: 44px;
}
.footer
{
height
: 44px;
}

二、fixed 与 input

要在有 input 标签的页面使用 fixed 定位,因为这两者在一起的时候,总是会有奇奇怪怪的问题。

在 iOS 上,当点击 input 标签获取焦点唤起软键盘的时候,fixed 定位会暂时失效,或者可以理解为变成了 absolute 定位,在含有滚动的页面,fixed 定位的节点和其他节点一起滚动。

其实这个问题也很好解决,只要保证 fixed 定位的节点的父节点不可滚动,那么即使 fixed 定位失效,也不会和其他滚动节点一起滚动,影响界面。

但是除此之外,还有很多坑比较难以解决,例如 Android 软键盘唤起后遮挡住 input 标签,用户没法看到自己输入的字符串,iOS 则需要在输入至少一个字符之后,才能将对应的 input 标签滚动到合适的位置,所以为了避开这些难以解决的坑,在有表单输入的页面,尽量用absolute 或者 flex 替换 fixed。

三、input 的 compositionstart 和 compositionend 事件

在 Web 开发中,经常要对表单元素的输入进行限制,比如说不允许输入特殊字符,标点。通常我们会监听 input 事件:

inputElement.addEventListener('input', function(event) {
let regex
= /[^1-9a-zA-Z]/g;
event.target.value
= event.target.value.replace(regex, '');
event.returnValue
= false
});

 

这段代码在 Android 上是没有问题的,但是在 iOS 中,input 事件会截断非直接输入,什么是非直接输入呢,在我们输入汉字的时候,比如说「喜茶」,中间过程中会输入拼音,每次输入一个字母都会触发 input 事件,然而在没有点选候选字或者点击「选定」按钮前,都属于非直接输入。

所以输入「喜茶」两个字,会触发6次 input 事件,如果把每次 input 的 value 打印出来,结果如下:

这显然不是我们想要的结果,我们希望在直接输入之后才触发 input 事件,这就需要引出我要说的两个事件—— compositionstart 和 compositionend。

compositionstart 事件在用户开始进行非直接输入的时候触发,而在非直接输入结束,也即用户点选候选词或者点击「选定」按钮之后,会触发 compositionend 事件。

var inputLock = false;
function do(inputElement) {
var regex = /[^1-9a-zA-Z]/g;
inputElement.value
= inputElement.value.replace(regex, '');
}

inputElement.addEventListener(
'compositionstart', function() {
inputLock
= true;
});


inputElement.addEventListener(
'compositionend', function(event) {
inputLock
= false;
do(event.target);
})


inputElement.addEventListener(
'input', function(event) {
if (!inputLock) {
do(event.target);
event.returnValue
= false;
}
});

添加一个 inputLock 变量,当用户未完成直接输入前,inputLock 为 true,不触发 input 事件中的逻辑,当用户完成有效输入之后,inputLock 设置为 false,触发 input 事件的逻辑。这里需要注意的一点是,compositionend 事件是在 input 事件后触发的,所以在 compositionend事件触发时,也要调用 input 事件处理逻辑。

四、iOS 1px border 实现

iOS设备上,由于retina屏的原因,1px 的 border 会显示成两个物理像素,所以看起来会感觉很粗,这是一个移动端开发常见的问题。解决方案有很多,但都有自己的优缺点。

0.5px border

从iOS 8开始,iOS 浏览器支持 0.5px 的 border,但是在 Android 上是不支持的,0.5px 会被认为是 0px,所以这种方法,兼容性是很差的。

背景渐变

CSS3 有了渐变背景,可以通过渐变背景实现 1px 的 border,实现原理是设置 1px 的渐变背景,50% 有颜色,50% 是透明的。

@mixin commonStyle() {
background
-size: 100% 1px,1px 100% ,100% 1px, 1px 100%;
background
-repeat: no-repeat;
background
-position: top, right top, bottom, left top;
}


@mixin border($border
-color) {
@include commonStyle();
background
-image:linear-gradient(180deg, $border-color, $border-color 50%, transparent 50%),
linear
-gradient(270deg, $border-color, $border-color 50%, transparent 50%),
linear
-gradient(0deg, $border-color, $border-color 50%, transparent 50%),
linear
-gradient(90deg, $border-color, $border-color 50%, transparent 50%);
}

这种方法虽然可行,但是没有办法实现圆角。

伪类 + transform

这类方法的实现原理是用伪元素的 box-shadow 或 border 实现 border,然后用 transform缩小到原来的一半。即使有圆角的需求也能很好的实现。

@mixin hairline-common($border-radius) {
position: relative;
z
-index: 0;
&:before {
position: absolute;
content:
'';
border
-radius: $border-radius;
box
-sizing: border-box;
transform
-origin: 0 0;
}
}
@mixin hairline($direct:
'all', $border-color: #ccc, $border-radius: 0) {
@include hairline
-common($border-radius);
&:before {
transform: scale(.
5);
@
if $direct == 'all' {
top:
0;
left:
0;
width:
200%;
height:
200%;
box
-shadow: 0 0 0 1px $border-color;
z
-index: -1;
} @
else if $direct == 'left' or $direct == 'right' {
#{$direct}:
0;
top:
0;
width:
0;
height:
200%;
border
-#{$direct}: 1px solid $border-color;
} @
else {
#{$direct}:
0;
left:
0;
width:
200%;
height:
0;
border
-#{$direct}: 1px solid $border-color;
}
}
}

 


推荐阅读
  • 本文旨在构建一个JavaScript函数,用于对用户输入的电子邮件地址和密码进行有效性验证。该函数将确保输入符合标准格式,并检查密码强度,以提升用户账户的安全性。通过集成正则表达式和条件判断语句,该方法能够有效防止常见的输入错误,同时提供即时反馈,改善用户体验。 ... [详细]
  • HTML5大文件传输技术深度解析与实践分享
    本文深入探讨了HTML5在Web前端开发中实现大文件上传的技术细节与实践方法。通过实例分析,详细讲解了如何利用HTML5的相关特性高效、稳定地处理大文件传输问题,并提供了可供参考的代码示例和解决方案。此外,文章还讨论了常见的技术挑战及优化策略,旨在帮助开发者更好地理解和应用HTML5大文件上传技术。 ... [详细]
  • 本地存储组件实现对IE低版本浏览器的兼容性支持 ... [详细]
  • DVWA学习笔记系列:深入理解CSRF攻击机制
    DVWA学习笔记系列:深入理解CSRF攻击机制 ... [详细]
  • 手指触控|Android电容屏幕驱动调试指南
    手指触控|Android电容屏幕驱动调试指南 ... [详细]
  • 在HTML5应用中,Accordion(手风琴,又称抽屉)效果因其独特的展开和折叠样式而广泛使用。本文探讨了三种不同的Accordion交互效果,通过层次结构优化信息展示和页面布局,提升用户体验。这些效果不仅增强了视觉效果,还提高了内容的可访问性和互动性。 ... [详细]
  • 本文介绍了如何利用摄像头捕捉图像,并将捕获的图像数据保存为文件。通过详细的代码示例,展示了摄像头调用的具体实现方法,适用于多种应用场景,如安全监控、图像处理等。 ... [详细]
  • 本文介绍如何在 Android 中自定义加载对话框 CustomProgressDialog,包括自定义 View 类和 XML 布局文件的详细步骤。 ... [详细]
  • 在分析Android的Audio系统时,我们对mpAudioPolicy->get_input进行了详细探讨,发现其背后涉及的机制相当复杂。本文将详细介绍这一过程及其背后的实现细节。 ... [详细]
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
  • 本文介绍了如何通过掌握 IScroll 技巧来实现流畅的上拉加载和下拉刷新功能。首先,需要按正确的顺序引入相关文件:1. Zepto;2. iScroll.js;3. scroll-probe.js。此外,还提供了完整的代码示例,可在 GitHub 仓库中查看。通过这些步骤,开发者可以轻松实现高效、流畅的滚动效果,提升用户体验。 ... [详细]
  • 在生产环境中进行高效部署与优化 ... [详细]
  • 下面的代码旨在输出其类文件的完整名称。对于不熟悉类字面量的读者,`Me.class.getName()` 方法会返回类的全称,例如 “com.javapuzzlers.Me”。通过这一机制,可以深入了解 Java 类加载和反射机制的内部工作原理。 ... [详细]
  • 在上篇文章的基础上,本文将继续探讨 Linux 设备驱动中的设备模型与 `devicedriverbus` 机制。在将设备注册到总线之前,需要先创建 `device` 对象。可以通过静态定义 `device` 结构体变量,并调用 `device_register` 函数来完成这一过程。此外,文章还将详细解析设备模型的内部工作机制,以及 `devicedriverbus` 机制如何实现设备与驱动的自动匹配和管理。 ... [详细]
  • 本文深入探讨了Android事件分发机制的源代码,重点分析了DecorView作为Activity根布局的角色及其在事件传递中的作用。同时,详细解析了PhoneWindow在Activity窗口管理中的关键功能,以及它如何与DecorView协同工作,确保用户交互事件的高效处理。 ... [详细]
author-avatar
挚爱—fruit
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有