折行文本末尾定位元素排版方案

说问题之前,先看一张图。

折行文本样图1

 

图中要求蓝色问号图标显示在文本末尾。

关于这个问题和app的同学讨论过,app同学表示实现有难度,让设计同学改了设计稿,将icon放到第一行文本后面,就如同第二行的“成人票”后面那样。

那么wap端能否实现这个效果呢,闭目思考下…

 

答案:能。

 

我们可以把icon直接写在文本后面,这样不就显示在行尾了么。

如果如此简单,app同学怎会轻易示弱,如果第二行只有icon(文字填满第一行),岂不是很难看。

那么我们绝对定位该icon到末尾。
.icon{position:absolute; right:-20px; bottom:0;}
然后我们希望这个元素能定位到我们想要的地方,那么我们希望这个元素的范围是这个样子的。

折行定位2

 

到此就比较明显了(虽然已开始我也没想到),只要设置该元素为内联属性(display:inline)就可以达到这样的效果了。

 

总结:虽然用了绝对定位,但从结构上来讲也还是合理的,主流浏览器都没问题,所以是个可行的方案。

最近看了《隐秘而伟大》,套用到这个问题上,inline虽然是行内元素的默认属性,但也有伟大的一面呀。

关于小米3安卓4.4ROM浏览器兼容问题

经过一些测试,小米3安卓4.4ROM回有一些不可预计的css和js不兼容问题。

可能是小米的开发在浏览器是做了一些优(wan)化(xiao)。

暂时看比较单行的问题是一个老版本swiper插件的拖拽有问题,更具体的还在测试中。

 

从用户的角度,碰到这种问题,影响了浏览,可以通过对浏览器设置->高级->浏览器标识的调整(应该只要不是默认就可以),来恢复正常浏览。

从开发者,用其他插件类库,或者干脆用自己写的东西,来规避这个问题。

健壮自己的代码与粗心战斗

想说的其实就是个代码容错率的问题。

最近出现了一下几个问题:

  1. cookie明明已经存好了,却无论如何取不到—— 是后端同事传cookie的时候在属性名上加了空格;
  2. 判断页面状态出现错误(不详述)—— 是用indexOf截取判断url的时候关键字过于简单(比如只判断了indexOf(“10”)),导致url被加入其他参数的时候判断目的出错;
  3. 多条件判断逻辑要清晰 —— 经常出现判断遗漏条件、默认执行条件有问题的情况;

以上的问题,思考一下,然后想一些方案来解决。

 

如何应对:

  1. getCookie的时候要对属性名清空格;
  2. 关键字尽量完整,因为这是不可预估的问题,测试环境可以方便测试使用,建议生产环境上干脆使用其他方式来达到目的;
  3. 判断要靠图来解决了,画出逻辑图,可以直观看出各个条件节点,带着图和产品确认逻辑也可以将风险外包(笑);

大学时候软件工程学习了代码的健壮性,但是每个人自律的情况不一样,再加上经验的差异,往往出现各种不可预知的问题。

最近吃了不少亏,但从大方向讲收获更多,以上分享给朋友们。

android 4.4.2 KitKat 更新对wap页面的一些影响

问题写在前面。

有的时候我们要跟app进行通讯或者跳转,会用到设定好的URL Schemes去做跳转。

有的开发者可能习惯了驼峰式命名,所以把地址协议也设置成firstSecond://这样的形式。

以前应该是没什么问题,新版本的安卓会把协议强制转换为小写,那么如果你的脚本对大小写敏感的话就要注意这个问题了。

 

下面列举一下官方的更新说明:

 

支持蓝牙MAP

Android现在支持消息访问协议(MAP)。因此,支持蓝牙功能的汽车可与您的设备交换消息。

支持Chromecast

借助Android设备和Chromecast,您可以在高清电视上尽情欣赏喜爱的精彩在线娱乐内容(例如来自Netflix、YouTube、Hulu Plus和Google Play的内容)。

Chrome网页视图

嵌入网页内容的应用现可使用Chrome快速、准确地呈现此类内容。

可选字幕

Android现在支持可选字幕和翻译字幕。要启用可选字幕,请转至“设置”>“辅助功能”,然后开启“字幕”。

内置设备管理功能

如果您丢失了设备,可以通过Android设备管理器找到该设备或清空设备数据。

经过重新设计的“下载”应用

“下载”应用经过重新设计,提供了新的排序选项、列表和网格视图,方便您管理下载的文件。

轻松切换主屏幕

如果您喜欢对设备进行个性化设置,并已安装一个或多个可供替换的主屏幕,则可以在“设置”>“主屏幕”中轻松切换。

经过重新设计的“电子邮件”应用

“电子邮件”应用经过全新设计,面貌焕然一新!现在,该应用不但提供文件夹嵌套、联系人照片等功能,还改善了邮件浏览体验。

全屏壁纸,支持预览

壁纸现在可延伸至通知栏和系统按钮区域。更换壁纸时,您可以先预览其效果再进行设置。*

HDR+拍摄模式

Nexus 5提供HDR+拍摄模式,可自动快速连拍多张照片,并将这些照片合成一张,实现绝佳的单张效果。白天拍摄的照片鲜活生动、光影分明;夜间拍摄的照片轮廓清晰、噪点寥寥。*

红外线遥控

在搭载红外(IR)遥控器的设备上,Android现在支持应用对电视和其他附近设备进行远程控制。

“快捷设置”中的位置信息设置

通过“快捷设置”中的新选项,您可以从任何地方快速调整您的位置信息设置。

位置信息模式和监测

如果您想要节省电池电量,请转至“设置”>“位置信息”,然后在“准确度高”和“耗电量低”位置信息模式之间切换。您无需在GPS、WLAN和移动网络设置之间切换。要查看最近有哪些应用申请使用您的位置信息,请转至“设置”>“位置信息”。

音频播放更省电

搭载Android 4.4的Nexus 5极大地延长了您收听音乐的时间,音频播放时间最长可达60小时。*

在锁定屏幕上调整音乐和电影播放进度

您可以在锁定屏幕上跳至歌曲或视频的某个片段。只需长按播放或暂停按钮,然后选择所需时间点即可。

安全的应用沙盒

应用沙盒功能已通过Security-Enhanced Linux得以强化。

内置计步功能

在Nexus 5上使用健身应用(如Moves)时,手机就相当于一个计步器,可用来计算步数。Android 4.4和新硬件可让您以更省电的方式评估自己的运动量。

以全新方式支持碰触付款

Android 4.4采用了全新的开放式NFC支付架构,支持所有移动运营商,允许应用管理您云端或设备上的支付信息。现在,您可以使用Google电子钱包或其他应用,在超过一百万家商店中使用碰触付款功能。

改进触摸屏

结合改进后的软件和Nexus 5的最新硬件,Android现在能以前所未有的速度和准确度,响应您的触摸操作。*

移动端上的点击事件

刚接触手机的时候,前端工程师喜欢用click去处理点击/触摸事件。
渐渐地,通过体验和看过一些文章,我们知道手机上还有touch专用事件,于是我们开始专用touchstart或者touchend来处理触摸事件,然后我们就碰到了各种问题…

Click的延迟问题

click从功能上讲问题不大,但是响应有延迟,传说300毫秒,其实根据机能不同会有更长时间的延迟。

据说一些安卓机用click会出现其他的问题,我没碰到过所以不细说了。

各种touch先天不足

touch响应快,但是你碰到屏幕就是一个touchstart事件,离开屏幕就是一个touchend事件,就算你去拖动屏幕也会执行触发这两个事件,产生的问题我们叫误点击。

解决响应时间和误点击的几个方案

首先我这里不谈jqueryMobile。

那么我知道的几个解决方案为:

fastclick,https://github.com/ftlabs/fastclick;

MBP.fastButton,https://github.com/h5bp/mobile-boilerplate

zepto的tap和singleTap事件,http://zeptojs.com/

上面几个方案都可以很好的解决响应和误点击问题。

那么我们进入正题——“连点”问题

什么是“连点”?
当你点击一个层,而这个层因为事件控制而隐藏了,这时候恰巧这个层下面的区域点击的同一个位置也有点击事件被触发了,那么就是“连点”了。

这个问题发生在弹出层的情况比较多。

上面提到的三个方案在新的手机里面都不太容易(总有特殊情况)出现“连点”问题,但是在老的安卓里面,比如我手上的三星Note中fastclick就会出现连点。

而其他方案表现就很好,所以从这个角度fastclick基本被淘汰了。

还有一种“连点”!

连点还有一种情况,就是你可能在事件里面写了个window.location.href跳转,你这个跳转非常快的完成了,然后又恰巧你跳转的页面在你点击的位置也有个点击事件/链接,那么这个事件/链接也会被触发。
这个是点击问题中最丧心病狂的~
而且关键的是除了click和a标签本身,其他方案都无法避免这个问题。

所以请避免使用点击事件做跳转。

父子Dom的点击事件关系

如果我的一个大dom上有个点击事件,dom中的子dom也有个点击事件,那么点击子dom会执行谁的事件呢?

如果你用click和fastclick就都会执行,其他的方案是执行子dom的事件。

综上所述

如果你在项目中用了zepto,请优先用zepto的相关点击事件,来避免可能发生的问题。
当然了fastclick还有其他的响应功能,如果你需要的话可以在合适的时候去使用它。

编写移动端网站你可能要准备的一些方案

很多pc端的页面仔想去编写wap端的页面,但是又因为对可能出现的问题有恐惧的心理而不敢出手?
pc和wap的网站虽然有很多差异,但是我们完全不用产生距离感,只要掌握一些主要问题的解决方案,大胆动手去做就好了。

这里介绍一套《HTML5移动Web开发实践》对wap的一些处理方案。

先下载这套代码和示例

https://github.com/h5bp/mobile-boilerplate

说明里面有对这个demo的说明

Mobile browser optimizations.
CSS normalizations and common bug fixes.
The latest jQuery.
A custom Modernizr build for feature detection and a polyfill for CSS Media Queries.
Home page icon for Android, iOS, Nokia, Firefox
Cross-browser viewport optimization for Android, iOS, Mobile IE, Nokia, and Blackberry.
Open Web App support for Firefox for Android and Firefox OS
Better font rendering in Mobile IE.
iPhone web app meta.
INSTANT button click event.
Textarea autogrow plugin.
Hide URL bar method.
Prevent form zoom onfocus method.
Mobile site redirection.
User Agent Detection.
An optimized Google Analytics snippet.
Apache server caching, compression, and other configuration defaults for Grade-A performance.
Cross-domain Ajax.
“Delete-key friendly.” Easy to strip out parts you don’t need.
Extensive inline and accompanying documentation.

 

对我们比较有用的有(不是按照上面顺序的哦):

移动浏览器的优化;
协助低版本浏览器兼容HTML5、CSS3的Modernizr(如果你是纯移动端开发者可以不考虑modernizr;
跨浏览器的视图优化;
更好的字体渲染;
点击事件的优化;
跨域ajax等。

当你了解并可以熟练使用上述功能后,wap浏览器的开发就是纸老虎了;)

iphone和其他平台载入页面时顺序问题

最近在用scrollTop的时候发现的一些问题。

在document.ready中使用scrollTop()获取当前滚屏的值。

假设页面有大于两屏的高度,先把页面拉到中间,然后刷新页面。

其他平台:

先将页面定位到刷新前的位置,然后获得滚动高度。

wap端(iPhone):

先获得滚动高度,再定位到刷新位置。

 

我在做lazyload的时候,因为这个问题iPhone的初始化出现了问题,在载入页面时无法正确的处理当前页面的图片加载。

 

暂时的解决方法有以下集中,

1、加个时间延迟,这样能保证页面跳转后执行初始化,但是要注意,如果你的时间延迟快过你页面构建的速度(ajax之类),还是无法读取到正确的滚屏高度。

2、价格window.scrollTop(0),因为获得高度默认为0,所以让设置他为0也可以达到相对正确的初始化。如果你要在页面加载的时候改变dom结构慎用。

Android禁用webview载入数据

咨询做安卓的同学,总得来说就两条:
webView.getSettings().setBlockNetworkImage(true);
webView.getSettings().setBlockNetworkLoads(true);
两条的功能就是阻塞对应类型的加载
如果要禁用就是true;
如果要启用就是false。
阻塞应该是为了加载速度快和安全着想。
实战中碰到的问题就是,wap端调用客户端的方法,客户端默认在方法回调结束后阻塞了加载,导致回调后再也无法请求ajax,使目标交互无法执行。
所以要根据实际情况选择是否阻塞。

seajs使用时出现的问题累积

加载jquery引用后出现报错

问题:
用正常的方法加载,jquery也确实载入到页面中了,但是引用的时候却说Object not defind。

解决:
引用的id要和jquery里面defind中的值互相对应才可以正常使用。

2.0版本取消了data-config和data-main的属性使用

问题:

解决:
按照常规的方式去引用配置文件和main初始化文件

浏览器缓存机制简介

这篇文章主要简单介绍浏览器缓存的机制,我们在做Server端响应时间优化的时候经常会接触到缓存的概念,例如经常会用到Memcached或Redis。我曾经使用缓存将原本一分钟才能获取的数据优化到了不到一秒的时间,当然,缓存也不是万能的,某些数据可以使用缓存或者必须使用缓存,有些数据则必须禁用掉缓存,确保每次请求返回的都是最新的数据,技术的运用方式是建立在业务的需求上的。

浏览器有一套自己的缓存机制,而在这个机制的基础上缓存规则的制定则主要依靠后端来实现,这属于一个合格的WEB开发者必须了解的内容。下文中提到的缓存概念,如果没有特殊说明都是指浏览器缓存,本文主要使用Chrome作为客户端,同时对Chrome开发者工具的一些细节进行了介绍。

什么是缓存?

引用Wikipedia上对Web cache的介绍,缓存就是:

A web cache is a mechanism for the temporary storage (caching) of web documents, such as HTML pages and images, to reduce bandwidth usage, server load, and perceived lag.

翻一下大意是:

WEB缓存就是临时存储WEB文档,例如HTML页面、图片等降低带宽使用、服务器负载、提升响应速度的一种机制。
我们使用的任何一个现代浏览器都支持缓存机制。

缓存在哪里?

IE浏览器:

我们可以通过IE的设置界面来查看缓存存放的位置:Internet选项->点击常规选项卡设置按钮->点击查看文件按钮即可自动打开缓存目录。如下图:

enter image description here

Firfox

查看Firefox浏览器缓存可以在Firefox地址栏输入about:cache来查看缓存详情,如图:

enter image description here

Chrome

Chrome并没有直接说明缓存目录、大小等具体信息,不过我们可以用Google查到,以Windows平台为例,Chrome的缓存目录在C:\Users\{{user name}}\AppData\Local\Google\Chrome\User Data\Default\Cache目录下。

Chrome Dev Tools NetWork简单介绍

首先我们对Chrome Dev Tools的NetWork功能做下简单的介绍。

当我们的浏览器向服务器发送请求时会携带一些基本的信息,如User-Agent、Cookie等,我们可以使用浏览器自带的开发者工具看到,如下:

// request header
GET /jquery.autocompleteV2.js HTTP/1.1
Host: 192.168.33.10
Connection: keep-alive
Cache-Control: max-age=0
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36
DNT: 1
Referer: http://192.168.33.10/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4,zh-TW;q=0.2
Cookie: cmTPSet=Y; ylCookie=ylCookie; tma=86847064.57393759.1402022771631.1402022771631.1402022771631.1; tmd=6.86847064.57393759.1402022771631.
服务器根据请求返回响应(response),响应头信息,如下:

// response header
HTTP/1.1 200 OK
Server: nginx/1.1.19
Date: Sat, 07 Jun 2014 13:32:29 GMT
Content-Type: application/x-javascript
Last-Modified: Sat, 07 Jun 2014 07:21:44 GMT
Transfer-Encoding: chunked
Connection: keep-alive
Content-Encoding: gzip
下图是Chrome Dev Tools下的网络请求的概览:

chrome_http_request_list

网络概览列表的Size Content栏,上边的数值Size表示响应大小,Size大小 = Content大小 + 响应头大小, Content表示响应内容实际大小,比如浏览器请求了一个实际尺寸为61093字节的文件,那么这里Content的值便为61093byte ÷ 1024 ≈ 59.7KB,Size值不一定大于Content的值,当我们在开启Gzip压缩的情况下Size的大小很可能小于Content的大小,开启Gzip后,尽管服务器没有直接告诉我们响应内容的Content-Length大小,但是浏览器拿到压缩后的响应内容是可以间接的反向计算出响应内容的原始大小的,还有一种情况是Content使用的是本地缓存,也就是服务器返回304状态码告诉浏览器继续使用缓存中的内容,Size的大小只是响应头的大小,Content大小为从缓存中读取的响应内容的大小。
当我们的光标移动到HTTP请求的timeline上时会显示网络请求时间花费的详细信息,如图:

http_timeline

这里涉及到几个名词,下面解释下Chrome NetWork Timeline状态名词的意义:

Blocking代表了等待当前已存在连接可用状态所花费的时间,相当于我们将请求A放入浏览器请求队列里面,浏览器依次处理队列里面的请求直到开始处理请求A所花费的等待时间。
Proxy代表了连接代理服务器所花费的时间。
DNSLookup代表了DNS查找花费的时间。
Connecting代表了创建连接所花费的时间,包括TCP连接建立、DNS查找、连接代理服务器与创建安全连接(SSL)所花费的时间总和。
Sending代表了发送请求数据所花费的时间。
Waiting代表了等待服务器响应所花费的时间。
Receiving代表了接收服务器响应内容花费的时间。
所以这里的Time Latency一栏Time代表了从我们创建请求到浏览器接收到服务器响应内容这个过程所花费的时间,Latency代表了从我们创建请求到服务器生成响应内容这段时间花费的时间。

缓存是如何工作的

更改Nginx配置,对所有js和css文件设置一套有效期为30天的缓存规则,Nginx站点配置添加代码:

location ~* \.(css|js)$ {
expires 30d;
}
重启Nginx服务使配置生效,清空浏览器缓存,模拟首次访问页面,刷新(请点击浏览器工具栏刷新按钮或使用右键菜单刷新功能刷新)页面。这时响应头会多出两个字段的数据:Cache-Control:和Expires,响应头变为了:

// response header
HTTP/1.1 200 OK
Server: nginx/1.1.19
Date: Sat, 07 Jun 2014 13:47:27 GMT
Content-Type: application/x-javascript
Last-Modified: Sat, 07 Jun 2014 07:21:44 GMT
Transfer-Encoding: chunked
Connection: keep-alive
Expires: Mon, 07 Jul 2014 13:47:27 GMT
Cache-Control: max-age=2592000
Content-Encoding: gzip
Cache-Control: max-age=259200表示缓存将在该页面请求后的259200秒后过期。
Expires: Mon, 07 Jul 2014 13:47:27 GMT表示缓存将在2014年7月7号 13:47:27后过期,注意:使用Expires指定过期时间,如果服务器时间和客户端时间不一致(这个问题很常见,在写这篇博客时,我的Ubuntu服务器时间比标准时间慢了4分钟),这时候通过Expires指定过期时间将达不到我们预期的效果,幸运的是绝大多数浏览器(IE6.0都支持HTTP1.1,还用怕什么?)和HTTP Server都已经支持HTTP/1.1,所以当响应头同时有Expires和Cache-Control时浏览器会优先考虑Cache-Control。

那在缓存期有效的这段时间刷新页面浏览器是如何使用已缓存的内容的呢?好,再次刷新(刷新方式同上)浏览器,服务器返回了304的status code,请求头变为了:

// request header
GET /jquery.autocompleteV2.js HTTP/1.1
Host: 192.168.33.10
Connection: keep-alive
Cache-Control: max-age=0
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.114 Safari/537.36
DNT: 1
Referer: http://192.168.33.10/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4,zh-TW;q=0.2
Cookie: cmTPSet=Y; ylCookie=ylCookie; tma=86847064.57393759.1402022771631.1402022771631.1402022771631.1; tmd=6.86847064.57393759.1402022771631.
If-Modified-Since: Sat, 07 Jun 2014 07:21:44 GMT
注意这里多了个If-Modified-Since字段,该值就是第一次响应头返回的Last-Modified字段,当服务器收到浏览器发送来的请求头时根据该字段判断是否让浏览器使用缓存内容,若在Last-Modified指定的时间后文件发生了变化服务器返回的status code变为200,同时会将最新的响应内容发送给浏览器,就像我们首次请求一样。如果在Last-Modified指定的时间后文件没有发生变化,服务器将返回status code变为304告诉浏览器:“你可以继续使用之前缓存的内容”,响应头变为:

// response header
HTTP/1.1 304 Not Modified
Server: nginx/1.1.19
Date: Sat, 07 Jun 2014 14:01:50 GMT
Last-Modified: Sat, 07 Jun 2014 07:21:44 GMT
Connection: keep-alive
Expires: Mon, 07 Jul 2014 14:01:50 GMT
Cache-Control: max-age=2592000
如果这段时间请求的文件内容发生了变化,服务器返回的status code变为200,同时响应内容为请求资源的最新副本,响应头内容变为:

HTTP/1.1 200 OK
Server: nginx/1.1.19
Date: Sat, 07 Jun 2014 14:03:00 GMT
Content-Type: application/x-javascript
Last-Modified: Sat, 07 Jun 2014 14:02:56 GMT
Transfer-Encoding: chunked
Connection: keep-alive
Expires: Mon, 07 Jul 2014 14:03:00 GMT
Cache-Control: max-age=2592000
Content-Encoding: gzip
当超出缓存有效期时,再次刷新页面,浏览器与服务器之间请求的协商过程也会验证请求资源是否被修改过,如果没有被修改缓存还是继续有效的,如果请求资源被修改过服务器将重新将请求资源的最新副本发送给浏览器。

页面刷新方式的区别

前面在演示时我们说到用指定的方式去刷新页面,那不同的刷新方式对于缓存会有什么效果呢?

一般常用有四种方式加载页面:

第一次请求时

首次请求初始化缓存机制,无特殊情况。

强制请求

强制请求一般是按下Ctrl + F5组合键来实现,强制刷新时浏览器会忽略一切缓存机制,告诉服务器“把最新的内容给我”,就像我们第一次打开这个页面一样。

一般刷新

常用的一般刷新方法有按下F5键或者在浏览器右键弹出菜单中刷新页面,这时浏览器与服务器之间将按照之前协商好的缓存协议进行对话。

点击浏览器转到按钮

通过浏览器地址栏转到一个已经打开过的页面浏览器将根据已缓存的请求资源是否已经过期来判断是否和服务器进行对话,如果缓存没有过期浏览器直接从缓存中读取数据作为响应内容,浏览器不会与服务器进行对话,不会发送任何的HTTP请求。

更详细的请参考下面的链接:

What requests do browsers’ “F5” and “Ctrl + F5” refreshes generate?
Behind Refresh Button
如何有效的控制缓存?

前面我们说过,当通过地址栏跳转到一个已经访问过的页面时,如果在之前设置的缓存有效期之内浏览器将不会与服务器进行任何协商直接读取本地缓存内容作为响应内容,那即使我更新了一段css代码,那么老访客看到的可能还是从本地读取的老旧的样式表文件,那怎么样才能让我更新的内容强制让客户端与服务器进行对话确认呢?简单:最常见的办法是在文件路径后面添加指定版本号,例如:

每次对文件的修改都要更新版本号,通过这种方式强制让浏览器与服务器进行对话,解决缓存的负面问题。

缓存的意义

合理的设置客户端端缓存可以最大限度的节省服务器网络流量开销、减轻服务器负载、提升用户体验等。

 

原文地址>>