那些年,开发Chrome应用踩过的坑

Chrome应用使用 HTML5、JavaScript 和 CSS 编写,提供与原生应用相同的体验的桌面应用。不过现在看来,使用Electron开发,可能是更明智的选择。下面介绍下我以前在开发Chrome应用遇到的那些坑。

坑1:页面不滚动

当网页高度超过视窗高度的时候,没有出现滚动条

解决方案:

html, body {  
  overflow: auto;
}

坑2:文字不能选中

尝试用鼠标选中文字时,发现竟然不能选中文字

解决方案:

html, body {  
  -webkit-user-select: text;
  user-select: text;
}

坑3:图片加载

由于chrome app的内容安全策略,外部图片是不能直接通过<img src="url">直接加载的。

解决方案: 方法1:

function loadImage(uri,callback){  
    if(typeof callback!='function'){
        callback=function(uri){
            console.log(uri);
        }
    }
    var xhr = new XMLHttpRequest();
    xhr.responseType = 'blob';
    xhr.onload = function() {
        callback(window.URL.createObjectURL(xhr.response));
    }
    xhr.open('GET', uri, true);
    xhr.send();
}

//使用方法
var imgUrl='http:xxx.jpg';  
loadImage(imgUrl,function(URI){  
    //Do some thing while image is load
})

方法2(angular):

angular.module('app')  
  .directive('blobSrc', function(){
    var directive = {
      restrict: 'A',
      link: linkFunc
    };

    return directive;

    function linkFunc(scope, elem, attr) {
      attr.$observe('blobSrc', function(url){
        if(!url) {
          return;
        }
        $http({
          method: 'GET',
          url: url,
          cache: true,
          responseType: 'blob'
        }).success(function(blob) {
          attr.$set('src', window.URL.createObjectURL(blob));
        });
      });
    }
  });

// 使用
<img blob-src="{{url}}">  

方法3(react):

import React, { Component, PropTypes } from 'react';

export default class Blobimg extends Component {  
  constructor() {
    super();
    this.state = {
      objectUrl: null
    };
  }

  componentWillReceiveProps(nextProps) {
    if(this.props.src !== nextProps.src) {
      this.getImage(nextProps.src);
    }
  }

  componentDidMount() {
    this.getImage(this.props.src);
  }

  getImage(src) {
    this.setState({
      objectUrl: ''
    });
    return fetch(src)
      .then(response => {
        return response.blob();
      })
      .then(blob => {
        let objectUrl = URL.createObjectURL(blob);
        this.setState({
          objectUrl
        });
      });
  }

  render() {
    return (
      <img src={this.state.objectUrl} />
    )
  }
}

Blobimg.propsTypes = {  
  src: PropTypes.string.isRequired
};

坑4:不能使用iframe

解决方案: 使用webview

坑5:链接点击之后不能打开

点击链接没有效果

解决方案: a标签增加target="_blank"属性

<a href="url" target="_blank">url</a>  

坑6:离线存储

不能使用localStorage

解决方案: 使用 chrome.storageIndexedDB

附我以前开发的两个chrome app:知乎日报 豆瓣FM