分类 Web 技术 下的文章

Thumb

canvas在安卓Hybrid框架下黑屏解决方案

记录下最近遇到的一个比较诡异限行的处理方案

场景:
安卓Hybrid app + Webview中加载的canvas + 复杂图形绘制 = 偶显canvas元素黑闪(黑屏)

也就是,在绘制canvas内容的时候,其他的DOM元素都是正常显示,唯独canvas元素会出现黑闪(黑屏)现象。

本来都已经想放弃Hybird转向原生app开发了,直到找到这篇文章。文章中介绍,部分版本的安卓系统不支持webview的canvas硬件加速,所以在很多情况下看到动画偶现黑屏,只要安卓的webview增加下面这行代码即可解决。

webView.setLayerType(View.LAYER_TYPE_SOFTWARE,null);

试了一下,确实可以,不过也会导致整体的速度变慢,这个速度的快慢程度取决于安卓设备的计算能力。所以在安卓设备上要想达到统一的效果是不太可能了,只能视实际情况而定,可以接受就用吧~

Thumb

移动端网页点击事件延时的解决办法

最近在一个Vue的项目中做了个虚拟键盘,结果遇到了点击延时问题。

第一反应,但是是去找 fastclick 的解决法案。但是发现在Vue项目中,并没有什么卵用~似乎是与Vue的点击事件有冲突,没时间也就懒得深入研究了。

接着搜到了一个 vue-tap 的项目,一试果然可以。。于是愉快的提交代码,下班嘚瑟去了~

但是。。。(如你们所料)万事都不可能这么简单的就能解决的~第二天又客户拿了一个设备来说点击还是有延时~心中还怀疑是否缓存的问题。结果怎么调试都还是有延时。。。(心中的草泥马已经无法压抑~)

正在纳闷的时候,突然想到,既然点击时间有延时,那我直接监听touchstart事件呢?毕竟是个虚拟键盘,并不需要只要能实现“点击”的效果就行。于是动手改了代码,一测试,果然。。。问题迎!刃!而!解!

回头再想想整个过程,我们在处理问题的时候,往往会将问题扩大化,而很多问题也许只需要换个思路,简单的改动就能解决~

代码就不上了,无非就是 @click="xxx" 改成 @touchstart="xxx" 而已~

Thumb

Vue2.0源码阅读笔记--双向绑定实现原理

作者:wj704 出处:http://www.cnblogs.com/wj204/p/6423478.html

一、实现双向绑定的做法

前端MVVM最令人激动的就是双向绑定机制了,实现双向数据绑定的做法大致有如下三种:

1.发布者-订阅者模式(backbone.js)

思路:使用自定义的data属性在HTML代码中指明绑定。所有绑定起来的JavaScript对象以及DOM元素都将“订阅”一个发布者对象。任何时候如果JavaScript对象或者一个HTML输入字段被侦测到发生了变化,我们将代理事件到发布者-订阅者模式,这会反过来将变化广播并传播到所有绑定的对象和元素。

2.脏值检查(angular.js)

思路:angular.js 是通过脏值检测的方式比对数据是否有变更,来决定是否更新视图,最简单的方式就是通过 setInterval() 定时轮询检测数据变动,angular只有在指定的事件触发时进入脏值检测,大致如下:
DOM事件,譬如用户输入文本,点击按钮等。( ng-click )
XHR响应事件 ( $http )
浏览器Location变更事件 ( $location )
Timer事件( $timeout , $interval )
执行 $digest() 或 $apply()

3.数据劫持(Vue.js)

思路: vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
由此可见,Object.defineProperty() 这个API是Vue实现双向数据绑定的关键,我们先简单了解下这个API,了解更多戳这里

Continue reading

Thumb

Vue下字符串转换为JSX方法

最近在群里看到有问到这个问题,然后自己又正好review到这部分的文档,就当作一个需求,做了一番研究,纪录一下。

需求:

将类似<div><span>{{ msg }}</span></div>的字符串直接转换为JSX数据,并挂载到vm中,以减少JS的代码量和复杂度(这应该也是Vue支持JSX的初衷吧)

解决:

文档可以看到,我们并不能直接把字符串变量拿来当JSX语法使用。不过幸运的是Vue提供了一个全局的compile方法,这个方法的作用就是在render函数中编译模板字符串,正如官方的例子:

var res = Vue.compile('<div><span>{{ msg }}</span></div>')
new Vue({
  data: {
        msg: 'hello'
  },
  render: res.render,
  staticRenderFns: res.staticRenderFns
})

我们可以将这段代码封装成一个专门用来解析的组件,就可以在需要时候使用了

const JSX = Vue.component('jsx', {
  render: function (h) {
    return Vue.compile(this.jsx).render.apply(this, arguments)
  },
  props: [
    'jsx'
  ]
})

总结:

如果你不需要解析一些变量,那么上面的代码就足够了。但是像上文所列的需求来看的话,你会发现msg这个变量没能解析出来,因为JSX这个组件里找不到msg变量,所以只能再增加个prop参数。不过这就牵扯出一个问题,有几个变量就要增加几个prop,这个目前误解(谁有好的解决方案,欢迎告知)

完整代码:

const JSX = Vue.component('jsx', {
  render: function (h) {
    return Vue.compile(this.jsx).render.apply(this, arguments)
  },
  props: [
    'jsx',
    'msg'
  ]
})

new Vue({
  el: '#app',
  data () {
    return {
      msg: 'hello',
      jsx: '<div>loading...</div>'
    }
  },
  components: {
    JSX
  },
  template: '<JSX :jsx="jsx" :msg="msg" />',
  created () {
    setTimeout(() => {
      this.jsx = '<div><span>{{msg}}</span></div>'
    }, 1000)
  }
})

在线示例:
https://jsfiddle.net/Hpyer/Lxd8mfmf/ (访问慢的自行翻墙)

Thumb

PrestaShop在nginx服务器下的伪静态规则

最近把web服务器换成了nginx,但是发现prestashop的图片怎么都不能显示,但是如果关掉伪静态,图片又能正常显示。想来想去就觉得问题应该是出在伪静态规则上。后来在网上找到了解决办法,只要把下面的代码放入nginx的对应网站的配置文件里就ok啦~

For PrestaShop 1.5.x (1.6.x没测试,不过个人感觉是兼容的)

rewrite ^/api/?(.*)$ /webservice/dispatcher.php?url=$1 last;
rewrite ^/([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$1$2$3.jpg last;
rewrite ^/([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$1$2$3$4.jpg last;
rewrite ^/([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$1$2$3$4$5.jpg last;
rewrite ^/([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$1$2$3$4$5$6.jpg last;
rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$1$2$3$4$5$6$7.jpg last;
rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$1$2$3$4$5$6$7$8.jpg last;
rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$7/$1$2$3$4$5$6$7$8$9.jpg last;
rewrite ^/([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ /img/p/$1/$2/$3/$4/$5/$6/$7/$8/$1$2$3$4$5$6$7$8$9$10.jpg last;
rewrite ^/c/([0-9]+)(\-[\.*_a-zA-Z0-9-]*)(-[0-9]+)?/.+\.jpg$ /img/c/$1$2$3.jpg last;
rewrite ^/c/([a-zA-Z_-]+)(-[0-9]+)?/.+\.jpg$ /img/c/$1$2.jpg last;
rewrite ^/images_ie/?([^/]+)\.(jpe?g|png|gif)$ /js/jquery/plugins/fancybox/images/$1.$2 last;
try_files $uri $uri/ /index.php$is_args$args;
error_page 404 /index.php?controller=404;

For PrestaShop 1.4.x

rewrite ^/([a-z0-9]+)\-([a-z0-9]+)(\-[_a-zA-Z0-9-]*)/([_a-zA-Z0-9-]*)\.jpg$ /img/p/$1-$2$3.jpg last;
rewrite ^/([0-9]+)\-([0-9]+)/([_a-zA-Z0-9-]*)\.jpg$ /img/p/$1-$2.jpg last;
rewrite ^/([0-9]+)(\-[_a-zA-Z0-9-]*)/([_a-zA-Z0-9-]*)\.jpg$ /img/c/$1$2.jpg last;
rewrite "^/lang-([a-z]{2})/([a-zA-Z0-9-]*)/([0-9]+)\-([a-zA-Z0-9-]*)\.html(.*)$" /product.php?id_product=$3&isolang=$1$5 last;
rewrite "^/lang-([a-z]{2})/([0-9]+)\-([a-zA-Z0-9-]*)\.html(.*)$" /product.php?id_product=$2&isolang=$1$4 last;
rewrite "^/lang-([a-z]{2})/([0-9]+)\-([a-zA-Z0-9-]*)(.*)$" /category.php?id_category=$2&isolang=$1 last;
rewrite ^/([a-zA-Z0-9-]*)/([0-9]+)\-([a-zA-Z0-9-]*)\.html(.*)$ /product.php?id_product=$2$4 last;
rewrite ^/([0-9]+)\-([a-zA-Z0-9-]*)\.html(.*)$ /product.php?id_product=$1$3 last;
rewrite ^/([0-9]+)\-([a-zA-Z0-9-]*)(.*)$ /category.php?id_category=$1 last;
rewrite ^/content/([0-9]+)\-([a-zA-Z0-9-]*)(.*)$ /cms.php?id_cms=$1 last;
rewrite ^/([0-9]+)__([a-zA-Z0-9-]*)(.*)$ /supplier.php?id_supplier=$1$3 last;
rewrite ^/([0-9]+)_([a-zA-Z0-9-]*)(.*)$ /manufacturer.php?id_manufacturer=$1$3 last;
rewrite "^/lang-([a-z]{2})/(.*)$" /$2?isolang=$1 last;