有用过handlebars的吗 想支持c 位运算有用吗怎么写

使用Handlebars模块化你的页面 - 简书
使用Handlebars模块化你的页面
Handlebars的layout和partials
Handlebars的layout文件和partials文件,可以是我们很轻松的组织一些公共的页面或代码片段,使得前端视图可维护性非常高。
Handlebars的layout文件
Express+express-handlebars项目中,我们定义好页面的layout文件后,然后在内容变化的位置加入{{{body}}},这样我们每次渲染页面都会替换到{{{body}}}中,这种“布局文件”的概念大大的降低了我们的维护成本。
Handlebars的partials文件
partials文件,也就是片段文件,可以放置公共的引用。在配置Handlebars的时候,我们可以指定partials文件目录:
var hbs = exphbs.create({
partialsDir: 'views/partials',
layoutsDir: "views/layouts/",
defaultLayout: 'main',
extname: '.hbs',
helpers: hbsHelper
这样在partials目录下定义的handlebars文件都会是partials文件,使用方法:{{& head}}。
下面是一个布局文件(layout.hbs),同时使用了partials文件,可供参考:
&!doctype html&
{{& head}}
&body class="hold-transition skin-blue layout-top-nav"&
&div class="wrapper"&
{{&header}}
&!-- Full Width Column --&
&div class="content-wrapper"&
&div class="container"&
{{{body}}}
{{&footer}}
&script src="/js/app.js"&&/script&
使用Helper实现段落功能
所谓段落功能,就是我们在页面预置一个位置,动态来渲染这个位置的代码(代码可以是html、js、或者css)。概念听起来可以有些模糊,我们举个例子:
我们已经知道,上面的layout.hbs文件是一个布局文件,所有的跳转页面都会通过这个布局文件来渲染内容,那么现在假如有一个个例页面(/hello请求渲染的页面),需要用js来处理一段代码呢?
alert('hello world');
如果我们在layout中加入这段js代码,那么所有的页面都会打印hello world,显然不是我们想要的,我们仅仅是想在请求/hello的时候打印。
用partials?可以吗?答案是不可以。partials仅能来组织公共的代码片段,不是用来个性化的。
那么又有童靴提出解决方案:在/hello渲染的页面底下加上不就行了吗?如:hello.hbs
这也是一种解决方案,但是出来的代码不伦不类,查看/hello渲染的页面源码:
```javascript
&!doctype html&
{{& head}}
&body class="hold-transition skin-blue layout-top-nav"&
&div class="wrapper"&
{{&header}}
&!-- Full Width Column --&
&div class="content-wrapper"&
&div class="container"&
alert('hello world');
{{&footer}}
&script src="/js/app.js"&&/script&
我们的script代码片段跑到container里了!这个简单的例子能满足需求,但是加入javascript片段依赖jquery,而jquery是在{{&footer}}里引用呢?这里肯定就会报错了。
使用Helper优雅的解决段落问题
Handlebars提供了强大的Helper支持,使我们解决这个问题变得简单明了。
首先我们定义一个helper,来组织这些个性片段(这些片段可能包含js、css、特殊的html等等)。
section: function(name, block){
if(!this._sections) this._sections = {};
this._sections[name] = block.fn(this);
在这个helper 中,我们定义了_sections变量(需要理解handlebars中的this关键字),当指定了_sections的name时,就会动态渲染session中的内容。
如何使用?首先我们可以在layout中预置一个section。如果我们渲染动态的js段落,需要放到{{& footer}}下面。以下是改造后的layout文件部分代码:
{{&footer}}
&script src="/js/app.js"&&/script&
{{{_sections.js}}}
说明:{{{_sections.js}}}这段是预置的代码,意思是从this._sections变量中取name为js的段落,渲染在这里。如果当前页面没有js则不渲染。
位置预置好了,我们就可以写具体的段落了。接上个例子,只想在请求/hello页面中打印hello world,就可以在hello.hbs中任意位置加入下面段落(最好是在页面最底下,方便维护)。
{{#section 'js'}}
alert('hello world')
{{/section}}
这样当我们请求/hello时,就会打印hello world,请求其他页面则不会有这段js代码。
养成良好的代码组织能力,有助于提高我们的编码质量!
Coding is 用智慧开创属于自己的事业!
联系邮箱:这是一篇Javascript模板Handlebars.js关于完整的教程,同时也可以作为一篇参考。Handlebars.js是一个Javascript客户端的模板引擎(它也能用于服务器端)。它是一个Javascript库,就像你在页面中包含其他.js文件一样。有了它,尼克在你的HTML页面内添加模板,模板会被你通过Handlebars.js函数传递的数据中的值解析或者插值。
它是怎样运行的:Handlebars.js是一个由Javascript构建的编译器,它接收任意HTML与Handlebars.js表达式并将它们编译为Javascript函数。这个派生出来的Javascript函数接着接收一个参数,一个对象 - 即你的数据 - 然后它返回一个包含HTML以及被插值在HTML中的对象属性值的字符串。因此,你最终可以得到一个对象属性值位于相应地方的字符串(HTML),你可以将这个字符串插入到页面中。
我一定要使用一个Javascript模板引擎吗?为什么?
是的,如果你正在开发或者计划开发Javascript应用,你应该使用一个Javascript模板引擎使你的HTML与Javascript充分解耦,这让你更加容易的管理的你的HTML与JS文件。
的确,你可以使用JSDom,或者你可以使用服务器端的模板然后通过HTTP传送HTML文件。但是我推荐使用客户端的模板因为它比起服务器短的模板来说更快,并且它提供更简单的方式去创建和维护模板。
另外,几乎所有的Javascript前端框架都使用一个Javascript模板引擎,因此无论是使用一个Javascript前端还是后端框架,你都会渐渐开始喜欢上Javascript模板的。
什么时候使用JS模板以及为什么要使用Handlebars.js?
有几种特殊情况需要使用Javascript模板引擎。
什么时候使用一个Javascript模板引擎?
在下列情况中,你应该使用一个Javascript模板引擎,比如Handlebars.js:
当你使用一个Javascript前端框架时,例如Backbone.js,Ember.js等等,大多数Javascript前端框架依赖于模板引擎;
应用视图(HTML页面或者部分页面)会被频繁的更新,尤其是通过REST API获取的服务器端数据或者来自客户端的数据发生改变时;
你有一些依赖于服务器端数据的科技栈(tech stacks),并且你想要所有的科技栈都获取同样的数据时;
你的应用具有更强的交互性和响应性;
你想要轻松的管理你的HTML内容;你不想在Javascript代码中包含任何重要的HTML标记。下面是一个混合着HTML标记的JS代码的例子(这使得管理你的HTML标记变得困难):
shoesData.forEach (function (eachShoe)
//注意到HTML与Javascript混杂在一起,这让人非常厌恶:
theHTMLListOfShoes += '&li class="shoes"&' + '&a href="/' + eachShoe.name.toLowerCase() + '"&' + eachShoe.name + ' -- Price: ' + eachShoe.price + '&/a&&/li&';
return theHTMLListOfS
为什么使用Handlebars.js(从8个或者更多的模板引擎中选择)?
对于有那么多的Javascript模板引擎,我一点也不意外,但是我们在这里只关注Handlebars.js,是因为它在很多方面都是最好的。其他值得一看的优秀模板引擎室Underscore.js的Template,Mustache.js,EJS和Dust.js。
Handlebars.js是Mustache Javascript模板语言的扩咱;它是Mustache.js的超集。
为什么使用Handlebar.js?有以下几个原因:
- Handlebars 是最先进的(能够预编译和其他方面),功能丰富的,以及流行的Javascript模板引擎之一,它拥有非常活跃的社区。
Handlebars是一个缺少逻辑的模板引擎,这意味着它和你的HTML页面一样几乎没有逻辑。使用Handlebars以及其他模板inquire最重要的一点就是让你的HTML页面保持干净整洁以及使它于基于逻辑的Javascript问价你解耦,Handlebars在这方面做的很好。另外,Dust.js也是一个缺少逻辑的模板引擎,它很适合作为Handlebars.js的替代品。
更进一步,目前最尖端的Javascript框架Meteor.js和Derby.js- 它们非常有希望在未来几个月内成为主流 -都使用了Handlebars.js。具体来说,Meteor.js使用了Handlebars.js,Derby.js的模板语法很大程度上是基于Handlebars的模板语法。另外,Ember.js也使用了Handlebars。
尽管Backbone.js自带了Underscore.js的模板引擎,在Backbone.js中使用Handlebars.js也是非常容易的。
因此,你将从学习Handlebars.js中获得的经验与知识是非常超值的,如果你正在使用,或者计划使用任何在上面提到的JS框架的话。
简单来说,学习Handlebars.js将会是一笔投资和一个明智的选择:你将能更加高效的编程,你可以轻松运用任何在未来出现的JS框架。
Handlebars.js概述
现在我们已经知道了怎样在一个简单的应用中使用Handlebars了,接下来我们更加深入的学习Handlebars。
Handlebars是怎样运行的?
在前面介绍过:andlebars.js是一个由Javascript构建的编译器,它接收任意HTML与Handlebars.js表达式并将它们编译为Javascript函数。这个派生出来的Javascript函数接着接收一个参数,一个对象 - 即你的数据 - 然后它返回一个包含HTML以及被插值在HTML中的对象属性值的字符串。因此,你最终可以得到一个对象属性值位于相应地方的字符串(HTML),你可以将这个字符串插入到页面中。
听上去要比实际的复杂很多,我们来看看具体的部分。
Handlebars模板的3个主要部分
使用Handlebars,首先你需要将Handlebars.js文件链接进你的HTML页面的head块中,就像你添加jQuery和其他.js文件一样。在具体使用中一共有三个主要的代码块:
Handlebars.js表达式
Handlebars表达式由Handlebars表达式和任何HTML内容或者在表达式中的Handlebars表达式组成(如果表达式在一个块中)。
一个简单的Handlebars表达式如下所示(这里的“content”可以是一个变量或者一个辅助函数-带或者不带变量):
{{ content }}
或者像下面这样,一个Handlebars块级表达式的情形(我们将在后面具体讨论):
HTML content and other Handlebars expression go here.
下面是一个带有HTML的Handlebars表达式。customName变量是一个通过pile函数被插值的属性(它的值将在这个地方被插入):
&div& Name: {{ customName }} &/div&
输出结果如下(如果customName变量的值是"Richard"):
既然你必须把Handlebars表达式(包含任意HTML)传递给 pile函数,Handlebars模板必须使用一个script标签包裹起来。的确,当模板位于它自己的HTML文件中时,script标签并不是必需的,但是当Handlebars模板与其他Handlebars模板以及其他HTML内容位于同一页面时,script标签必不可少。
-- Script 标签
HandlebarsMibang内嵌在script标签中(在这里script标签的type属性被设置为"text/x-handlebars-template")。这里的script标签和平时在HTML页面中使用内嵌Javascript代码是所用的script标签一样,除了type属性有所差别。你从script标签中获取HTML内容并将它传递给pile函数。
下面是一个Handlebars script标签的例子:
&script id="header" type="text/x-handlebars-template"&
&div& Name: {{ headerTitle }} &/div&
Date(或者上下文)
Handlebars模板代码的第二个部分是你想要展示在页面山高的数据。你将你的数据作为一个对象(一个正常的Javascript对象)传递给Handlebars函数。这个数据对象叫做上下文。这个对象能够由数组,字符串,数字,其他对象组成,或者是包含所有的东西。
如果数据对象拥有一个对象数组,你可以使用Handlebars中的each辅助函数(稍后将讨论辅助函数)去迭代数组,此时的上下文将被设定为数组中的每个对象。
下面是一个在Handlebars模板中设置数据对象并进行迭代的例子:
--拥有对象数组的数据对象
//自动以对象拥有一个包含对象的数组,我们可以将它传递给Handlebars:?
var theData = {customers:[{firstName:”Michael”, lastName:”Alexander”, age:20}, {firstName:”John”,
lastName:”Allen”, age:29}]};
你可以像下面这样使用each辅助函数来迭代自定义对象:
或者,既然我们将一个对象数组作为自定义对象进行了传递,我们可以使用block辅助函数(稍后会讨论)语句来直接指向自定义对象,如下所示:
&script id="header" type="text/x-handlebars-template"&
{{#customers}}
&li& {{ firstName }} {{ lastName }} &/li&
{{/customers}}
--拥有字符串的数据对象
//在这个例子中,数据对象包含字符串属性
var theData = {headerTitle:"Shop Page", weekDay:”Wednesday”};
&script id="header" type="text/x-handlebars-template"&
&div& {{ headerTitle }} &/div&
Today is {{weekDay}}
3.Handlebars编译函数
Handlebars模板的最后一块实际上是一个两步执行的步骤:
1. 使用Handlebars编译函数编译模板;
2. 接着将数据对象传递给这个被编译的函数并调用(即将数据对象作为它的唯一参数)。它将返回一个嵌套这对象值的HTML字符串并将其插入到HTML中。
简单来说:
Handlebars编译函数接收模板作为参数并返回一个Javascript函数。我们接着使用这个被编译的函数去执行数据对象并返回一个嵌套着对象值的HTML字符串。然后我们就可以将这个字符串插入到HTML页面中了。
下面我们将三块代码合并一下:
1.在HTML页面上:通过使用Handlebars表达式设定模板,将模板添加到script标签中:
2.在Javascript文件中,初始化数据对象:
var theData = {headerTitle:"Shop Page", weekDay:”Wednesday”};?
//从第一步设定的script标签中提取HTML
//在页面中我们使用script标签的id()header)来定位它?
var theTemplateScript = $("#header").html();
?3.依然在Javascript文件中:我们使用Handlebars编译函数来编译模板。
编译从script标签汇总提取的模板:
//Handlebars编译函数返回一个函数赋值给theTemplate变量
var theTemplate = pile (theTemplateScript);
?使用有编译函数返回的theTemplate()函数去生成最后经过插值的字符串。我们将数据对象作为一个参数进行传递。接着将返回的HTML字符串插入页面中:
$(document.body).append(theTemplate(theSata));
?它将返回一个嵌套有数据对象值的HTML字符串,返回结果如下所示:
Today is Wednesday
本文译自Handlebars.js Tutorial: Learn Everything About Handlebars.js JavaScript Templating ,原文地址 ,转载请注明出处
如果你觉得本文对你有帮助,请点击下面的链接给我提供赞助
本站专栏文章皆为原创,转载请注明出处(带有 前端乱炖 字样)和本文的显式链接(),本站和作者保留随时要求删除文章的权利!
添加了一枚【评注】:如果将handlebars作为一个独立的文件,文件的后缀名叫什么?是.hmtl?然后怎么把他引入到index.html里面? 谢谢~
添加了一枚【评注】:如果将han
WRITTEN BY
PUBLISHED IN
本专栏其他文章
浏览:5939赞:0
浏览:23078赞:1
浏览:19819赞:0& 应用背景
我们在做项目时,为了使页面模块高度复用,使用页面模板是必须的,我想大家通常可能会新建MVC的项目,然后在页面中使用Razor引擎,新建Helper模板类,前后台代码的混写,简洁高效,一切都是那么的行云流水,我就是这么干的! 直到有一天,当我快做完一个项目时,经理对我说,你不要直接访问数据库,用接口就行了,是啊,说的多轻松,但对程序员来说这就是晴天霹雳啊,因为这意味着你这个项目的流程彻底改变。
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &变成
初看起来好像没什么大的问题,砍掉整个后台好像还方便了不少,但还是有些问题,因为接口返回的是json数据,所以会遇到下面的问题:
即你怎么把json数据传给你的Helper模板? 看来Razor是不行了,那怎么办呢? 在js方法中拼凑html字符串,类似
var html = "&div style='display: inline' id='" + id + "'&" +
"&span&" + obj.title + "&/span&&img onclick=\"removeregion('" + id + "')\" src='../images/delete.gif'&" +
& & 这当然可以,但如果页面稍微复杂一些,在各个标签中都有事件,方法,并且方法还要携带相关参数,再加上相应的css样式,业务逻辑之类的,这一大锅混在一起,你觉得你还能这么干吗?
即使在页面很简单的时候,我也从没考虑过用这种作死的办法来解决问题。难道就没有一种类似Razor的前台的东东,可以使数据、业务逻辑、页面呈现清晰完美的结合在一起吗?答案是肯定的,我们的前辈们早就遇到过这类问题,并且他们已经为我们提供了非常好的解决方案:
HandlerBars是一个非常给力的前端语义构建模板,能帮助你快速高效的搭建出自己的页面模型。 &
简单使用:
1.新建MVC项目&
& & & & & &
& &2.下载HandleBars.js.(官网的好像失效了,可以去,或直接NuGet)& &
4.建立模板&
& & & & & & & & & & & & & & & & & & & & & & & & & & & & & & 注意type的类型
& 5.编译并输出
我们还可以带参数
有效组织:
我在学习Handlebars时发现网上的很多教程只是为了写教程而写教程(废话啊),我的意思是说没有更多的从实际开发的角度去帮助大家理解和使用。 就像上面的例子(虽然很水,但能说明问题即可),你可以看到,我的模板、js 、包括之后可能有的css几乎都是写一起的,这在实际的项目开发中是很不可取的,怎样更好的使各个部分相互独立,互不影响,且又能更好的组织和使用呢? 经过我的大量测试和试验发现了以下三个结论:
1.handlebars的模板必须在使用前存在于dom中,即如果你要在一个分部视图中调用模板,那么在你这个分部的视图或它的父级视图中必须存在你要调用的模板。
2.在handlebars模板中不能像Razor那样嵌入js。
3.模板无法像Razor 那样放在App_Code中直接访问。
好了,这里的关键就是怎样更好的组织模板文件呢!针对这三个特点,我们可以在使用时这样组织:
1.新建模板文件夹,里面存放handlebars模板(就是一个cshtml文件)。
你可以看到,我的一个模板文件里只存了一个模板,当然如果你能保证不冲突的话,你也可以在一个文件中写多个。
2.将该模板用到的js,css单独存放于一个文件(这个不用说,大家都知道!)。
3.在Bundle中一次将你要用到的js,css打入,并在母版页中Render。
4.关键就是这一步了,在你要用到模板的页面或父级页面导入你在第1步创建的模板文件
然后再在js里引用,编译,输出就像上面那个很水的demo一样。
这样我们的模板、js、css就都分开了,层次结构也更清晰,一目了然。
以上就是个人在工作学习中的一点经验和见解,和大家分享一下,希望能帮到大家,本人菜鸟一名,若有不对之处,欢迎大家批评指正! & &
阅读(...) 评论()Android Webview遇到的问题——记新版广告墙开发
前一阵很辛劳,所以荒废了博客。前几天终于完成了这项艰苦卓绝的工程:,决定写篇文章,记录一下踩过的坑。
广告墙属于典型的列表式应用:打开后是无尽列表,通过滑动手指驱使列表滚动,上拉加载更多内容,下拉刷新列表(这次没做)。单击列表中的某项,打开详细页;单击上面的后退按钮,退回上一级页面。
考虑到目标平台是Android系统,内嵌WebKit内核,我采用了时下流行的HTML5+CSS3技术,并且做好了向下兼容的准备。为了减少代码量,我放弃了,也没有考虑半调子,全部使用原生开发。操作上,开始想用封装手势,后来处理滚动效果处理得不好,最终选择了。模板方面,前端使用,后端使用,所以编译时还写了段代码做转换。
项目代码托管在,因为前端不涉及到业务逻辑,所以仓库是公开的,有兴趣的同学以clone下来看看。
技术选型大概聊这些,接下来开始进入正题。
性能vs兼容性
实际上,随着硬件的发展,对于列表式这种非性能敏感性应用来说,性能早已不是制约其发展的首要因素了。另一方面,有一定专业精神的前端如我,平时也会注重积累各种性能优化的点,并不断在项目中实验、实施——所以我就很搞不明白,技术实力强大如,为啥会弄出个这种完全不能用的东西出来……
相反,在这个项目中,由于平台分裂带来的兼容性问题成了最大的绊脚石。尤其是这些兼容性问题,极少找到现成的解决方案……下面举两个例子:
Vivo X909 和z-index
正常情况下,position:的dom节点在不显式设置z-index属性区分层级的时候,默认后面的节点会显示在前面的节点上方。大多数浏览器里都是这样,可是Vivo
X909就不行。
列表大家都知道,点击某项,详情会从右边滚动进来。由于没有设置-webkit-tap-highlight-color(现在想想应该做的,下周回去加上吧),所以这个bug当时的的表现是“单击没有反应”。这种情况很难调试,我开始以为JS有错,试了很久,后来配置好(见),才找到症结所在。最后把几个图层分别加上z-index,问题解决。
早期Android的animation-fill-mode
我们仍有20%的用户在使用2.3.x版本的Android,所以这块市场必然不能放弃。在小米2上调是好的动画,在老HTC G10上,滑出的图层在动画结束后会消失。这次好在有了上次的经验,直接上;加上也有明确的描述,所以很快解决了。
各种难以定位、缺少文档、找不到解决方案的兼容性问题层出不穷,让我不禁感慨:本以为买上了WebKit的康庄大道,谁知尼玛这豆腐渣工程下面全是坑啊……
前面提到,开始时间比较富裕,我也比较自信,想借助,慢慢打磨出色的滚动体验。后来无尽的bug环伺左右,实在无法专心研究,便退而求其次,使用了。
如今已经发展到5,其作者自信的表示:“我尽全力提升了其在Android平台上的表现,我相信现在它已经达到了极致。”实验效果确实很理想,无论是高配置的小米,还是老旧的HTC
G10,都表现出色。将来有空的时候得好好研究下他是怎么做的。
随着时代发展,Web开发这种脚本语言也开始分裂成开发、部署两个阶段,这是个好事情。核心代码需要为维护、测试留下足够的空间,势必在性能表现上有所不足,部署时根据应用场景的不同输出不同的结果正好能解决这个问题。这个项目中我使用,花费了不少精力在编写上。
开发时,我将测试用的数据,按照设计好的数据结构写在define.js中,生产环境中用服务器生成真实数据来替代。不同的应用场景,也用其配置。如今,目标支持的6个场景都能稳定工作,效果不错。
Windows下不好配ruby,使用是个问题,不过后来找到了,问题迎刃而解。
技术细节分享
简单构造选择器
功能确实强大,不过实在太重型了;备胎轻便一些,不过功能也弱一些,语法做不到全兼容,用起来不舒服。仔细考虑这个项目的需求,无非是:找到某个元素,给它添加事件侦听;或者判断它是否包含某个class,那么自己写一个直接到Dom节点的选择器就足够了。后来看到篇文章,里面详细测试了querySelector和getElementById众的性能,发现还是后者大大领先——尤其在移动平台上,于是基本放弃了用前者的念头。
这个选择器实现起来很容易:
var $ = window.$ = function (selector, root) {
root = root ||
switch (selector.charAt(0)) {
selector = selector.substr(1);
dom = document.getElementById(selector);
selector = selector.substr(1);
dom = root.getElementsByClassName(selector)[0];
dom = root.getElementsByTagName(selector)[0];
另外,$还可以用来当命名空间,保存一些需要全局使用的变量和方法。
使用Handlebars.js生成预编译模板
预编译模版可以降低运行时的运算量,对于移动开发这种能省则省的应用场景,实在是必备之物。另一方面,为了方便开发,把模版放在HTML里更好调整。好在有“编译输出”这个步骤,可以两全其美。
的预编译是把模版转换成根据数据生成HTML的JS代码,可以使用压缩。编译之前最好过滤掉多余的空格和换行符,这样生成的JS文件也会小很多。
当然,再预编译也不如直接渲染HTML来的快,所以在服务器端生成页面的时候,一定要包含实际内容,让用户尽快得到信息。而PHP没有现成的实现(我也不打算写),好在有,并且(其实不完全,也被坑了),所以我写了一小段代码。
使用attr()实现CSS中的多语言
除了传统的中文版,这次还要制作英文版。英文版与中文版的功能几乎完全一致,只是文字全部换成英文。最简单的做法就是搞个en.html——因为使用了模版,JS里不包含任何文字内容;但是“上拉加载更多”这个功能目前使用CSS的:after实现——初衷是不修改dom,不引起relayout——当然,反正我用着,增加个语言包不难,不过我还是希望把修改集中在一个地方。
后来查了下,发现Android
2.1起就支持,那就好办了,先把各阶段文案放到HTML的属性里:
&div id=&list& data-normal=&继续上拉,加载更多广告& data-more=&松开加载& data-loading=&加载中...& data-no-more=&没有其它广告了,再看看吧& data-error=&加载失败,请稍候重试& data-over=&&&&/div&
&div id=&list& data-normal=&Pull up to load& data-more=&Release to load& data-loading=&Loading...& data-no-more=&No more ads& data-error=&Load failed& data-over=&&&&/div&
然后在CSS里使用attr()访问即可
#list.over
content: attr(data-over)
#list.more
content: attr(data-more)
#list.loading
content: attr(data-loading)
#list.no-more
content: attr(data-no-more)
#list.error
content: attr(data-error)
WebKit中z-index、translateZ(0)混用,导致click事件半失灵的解决
要在浏览器里触发下载,只要链接到一个浏览器打不开的文件就行。链接跳转是在click触发的浏览器内建行为,换言之,链接跳转依赖于click的正常触发。
click比touch
event晚200~300ms,所以为了保证用户体验,我们通常用tap(touchstart&+&touchend)来替代click响应用户操作
所以一个“点击下载按钮”的操作,就会先响应tap事件,弹出详情浮层,告知用户获得积分的最终条件,然后等待浏览器开始下载
CSS动画最好使用translateZ(0)促使浏览器启用GPU加速
这个bug在以上条件下产生,影响这个过程
之前我在PC版Chrome里也曾见识过这个bug(最新版没验证,大概20+的时候吧)。具体表现为,一个层,它的translateZ有赋值,它可能被移到某处(通过translateX和translateY,或者动画过程中),不过还未到达那里,但是它仍然会拦截那里mousedown/mouseup事件,导致click事件无法正常触发。
这个bug非常难排查,因为它并不影响tap;视觉上看不到那个层,会想当然的认为不应该跟那个层有关系;并且,WTF,如果按得时间稍长,比如半秒,就可以触发click……因为触发条件比较复杂,我甚至很长时间没找到规律。最后只好请出“小黄鸭调试法”,试图向索隆解释发生了什么,然后发现无法正常下载的按钮都是被详情浮层遮盖着,继而回忆起以前解决过类似问题。
最后解决这个问题的方案我其实不很满意,不过确实能顺利工作:
层的当前位置不会覆盖按钮,先不给层增加动画
tap后,给click留出足够的时间(我这里用400ms),再给层添加动画
确保click可以响应,通过setTimeout给层添加动画——本来300ms就测试通过,不过为了保险,我还是决定写成400
仍然悬而未决的问题
虽说项目已经快上线了,但仍有几个不解之谜……
某些手机仍然无法下载(启动&a&)
快速拖动的时候可能把内容拖走(应该是触发了浏览器默认行为)
做完项目回头看,系统分裂造成的兼容性问题比想象中多很多,原先以为最多是有些2.x版本不支持,做向下兼容就好,谁知还有各种实现细节问题。不过,在PC Chrome + 手机Chrome +&&+&alert之后,只要有耐心,大多数问题时可以解决的。
说完开发效率,另一方面再来看看产品表现。我们对性能不需要太乐观,也不用太悲观,敏感型应用,老老实实用原生开发,或编译成原生应用;非敏感型,跨平台高兼容性(咦,这眼泪哪里来的)的优势很明显。通过我实际看到移动端的表现,我们这些页面仔应该更有信心,将来移动大市场里,Web App的份额绝对不比Native App要少。
这项事业任重而道远,需要我们一起努力。
转载网址:
看过本文的人也看了:
我要留言技术领域:
取消收藏确定要取消收藏吗?
删除图谱提示你保存在该图谱下的知识内容也会被删除,建议你先将内容移到其他图谱中。你确定要删除知识图谱及其内容吗?
删除节点提示无法删除该知识节点,因该节点下仍保存有相关知识内容!
删除节点提示你确定要删除该知识节点吗?

我要回帖

更多关于 c 位运算有用吗 的文章

 

随机推荐