前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
AI 面试
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
AI 面试
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航

好物快应用、H5端开发小结

首页2018-10-19 16:50:43Front-End
JavaScript快应用

# 一、deepLink跳转

# 1.1 快应用中呼起deepLink

第一步:检测是安装了app

前提条件:需要知道app的包名

// 判断用户是否安装了app
export const checkInstalledApp = (pkg_name) => {
  const pkg = require('@system.package')
  return new Promise((resolve,reject)=>{
    pkg.hasInstalled({
      package: pkg_name,
      success: function (data) {
        resolve(data.result) //返回true、false
      },
      fail: function (data, code) {
        reject(code)
      }
    })
  })
}
@前端进阶之旅: 代码已经复制到剪贴板

第二步:调起deepLink

let pkg = 'com.newsqq.fda' // 传入包名
let deep_link = '' // 跳转到app的地址
let params = {}

checkInstalledApp(pkg).then(hasInstalledApp=>{
    // 用户已经安装了app, deep_link直接跳转
    if(hasInstalledApp && deep_link){
      params = {uri:deep_link}
    }else{ // 否则跳转到H5地址
      params = {
        uri:'Webview',//对应于manifest中的配置
        params:{
          url,
          title:goods_name
        }
      }
    }
    this.$app.$def.router.push(params)
})

@前端进阶之旅: 代码已经复制到剪贴板

# 1.2 H5页面呼起快应用

引入快应用 官方提供的代码,这里做了一下处理

export const quickapp = (function(){
  !function(e) {
        "use strict";
        window.appRouter = function(e, t, a, o) {
            return a = a || {},
            o && (a.__PROMPT__ = 1, a.__NAME__ = o),
            n(e, t, a)
        },
        window.installShortcut = function(e, t) {
            return n("command", "", {
                type: "shortcut",
                package: e,
                name: t
            })
        },
        window.channelReady = function(e) {
            var n = {
                available: new Function,
                availableTimeout: 2e3
            };
            return "function" == typeof e ? n.available = e: "object" == typeof e &&
            function(e, n) {
                n = n || {};
                for (var t in n) e[t] = n[t]
            } (n, e),
            function(e) {
                var n = "http://thefatherofsalmon.com/images",
                t = document.createElement("img");
                if (t.style.width = "1px", t.style.height = "1px", t.style.display = "none", n += "/" + 1e20 * Math.random(), t.src = n, document.body.appendChild(t), t.complete) e.available.call(null, !0);
                else {
                    t.onload = function() {
                        clearTimeout(a),
                        e.available.call(null, !0)
                    };
                    var a = setTimeout(function() {
                        e.available.call(null, !1)
                    },
                    e.availableTimeout)
                }
            } (n)
        };
        function n(e, n, t) {
            var a = "http://thefatherofsalmon.com/",
            o = "";
            if (e && (a = a + "?i=" + e), n && (a = a + "&p=" + n),
            function(e) {
                if (!e) return ! 0;
                var n = void 0;
                for (n in e) return ! 1;
                return ! 0
            } (t)) {
                var i = window.location.search;
                i.indexOf("?") > -1 && (o = i.substr(1))
            } else {
                o = Object.keys(t).map(function(e) {
                    return e + "=" + encodeURIComponent(t[e])
                }).join("&")
            }
            "" !== o && (a = a + "&a=" + encodeURIComponent(o));
            var l = document.createElement("img");
            l.src = a,
            l.style.width = "1px",
            l.style.height = "1px",
            l.style.display = "none",
            document.body.appendChild(l)
        }

    } ();

    return {
      appRouter:window.appRouter,
      installShortcut:window.installShortcut,
      channelReady:window.channelReady
    }
})()
@前端进阶之旅: 代码已经复制到剪贴板

或者在网页中嵌入以下 js,支持HTTP与HTTPS访问。上面的代码和这个一样的,只是做了一下模块化处理

<script type="text/javascript" src="//statres.quickapp.cn/quickapp/js/routerinline.min.js"></script>
@前端进阶之旅: 代码已经复制到剪贴板

调起应用

appRouter(packageName, path, params, confirm), 更多详情

第一步:检测手机型号

只有在对应的应用商店上架才可以打开

  • 主要用到了这个库 https://github.com/hgoebl/mobile-detect.js
// 检测手机型号
export const checkPhone = ()=>{
  const MobileDetect = require('mobile-detect')
  let device_type = navigator.userAgent;//获取userAgent信息
  let md = new MobileDetect(device_type);//初始化mobile-detect
  let os = md.os();//获取系统
  let model = "";

  //判断数组中是否包含某字符串
  Array.prototype.contains = function(needle) {
      for (i in this) {
          if (this[i].indexOf(needle) > 0)
              return i;
      }
      return -1;
  }

  if (os == "iOS") {//ios系统的处理
      os = md.os() + md.version("iPhone");
      model = md.mobile();
  } else if (os == "AndroidOS") {//Android系统的处理
      os = md.os() + md.version("Android");
      var sss = device_type.split(";");
      var i = sss.contains("Build/");
      if (i > -1) {
          model = sss[i].substring(0, sss[i].indexOf("Build/"));
      }
  	let phoneModel = model.toLocaleLowerCase()
      //判断是否是oppo
      if(phoneModel.indexOf('oppo')!==-1){
      	return true
      }

  }
  return false
}
@前端进阶之旅: 代码已经复制到剪贴板

第二步:调起快应用

以呼起OPPO手机下已经上架的快应用为例

// H5页面中呼起快应用

// page你所在的页面标志,goods_id是传递的参数
export const openQuickapp = ({page,goods_id})=>{
  const appRouter = (path,params={})=>quickapp.appRouter('com.yesdat.poem',`/${path}`,params)

  // 检测OPPO手机下呼起唐诗三百首快应用首页
  if(!checkPhone()){
    return false
  }
  if(page == 'home'){
    appRouter('Home')
  }else if(page == 'detail'){
    appRouter('Detail',{goods_id})
  }else if(page == 'search'){
    appRouter('Search')
  }

}
@前端进阶之旅: 代码已经复制到剪贴板

# 1.3 H5页面呼起deepLink

H5 页检测手机是否安装 app 相关流程

uri获取

这里的uri,指得就是通过 Url scheme 来实现的H5与安卓、苹果应用之间的跳转链接。

我们需要找到客户端的同事,来获取如下格式的链接。

xx://'跳转页面'/'携带参数'
@前端进阶之旅: 代码已经复制到剪贴板

简单解释下url scheme。

  • url 就是我们平常理解的链接。
  • scheme 是指url链接中的最初位置,就是上边链接中 ‘xx’的位置。
  • 详细介绍可以看这里: 使用url scheme详解

用这个链接我们可以跳转到 应用中的某个页面,并可以携带一定的参数

具体实现

第一步:通过iframe打开App

Android平台则各个app厂商差异很大,比如Chrome从25及以后就不再支持通过js触发(非用户点击),所以这里使用iframe src地址等来触发scheme。

//在iframe 中打开APP
var ifr = document.createElement('iframe');
ifr.src = openUrl;
ifr.style.display = 'none';
@前端进阶之旅: 代码已经复制到剪贴板

第二步: 判断是否安装某应用

原理:若通过url scheme 打开app成功,那么当前h5会进入后台,通过计时器会有明显延迟。利用时间来判断。

  • 由于安卓手机,页面进入后台,定时器setTimeout仍会不断运行,所以这里使用setInterval,较小间隔时间重复多次。来根据累计时间判断。
  • 根据返回true false来判断是否安装。
  • document.hidden对大于4.4 webview支持很好,为页面可见性api

使用方式

# 二、剪贴板分享

主要是使用到clipboard简化

更多使用方式详情: https://github.com/zenorocha/clipboard.js

# 三、加载更多

h5页面需要分页加载优化,react中为例

第一步:封装一个loadMore组件

第二步:处理分页

需要后台支持分页

# 四、搜索历史

search-history

使用

fe
  • 一、deepLink跳转
    • 1.1 快应用中呼起deepLink
    • 1.2 H5页面呼起快应用
    • 1.3 H5页面呼起deepLink
  • 二、剪贴板分享
  • 三、加载更多
  • 四、搜索历史
  • 五、骨架屏的应用
  • 六、游客点赞
  • 七、nodejs递归文件夹上传到阿里云
  • 八、nodejs实现复制目录到指定文件夹
  • 九、优化

← jQuery的deferred对象详解学会使用Graphviz绘制流程图 →