
doodoo.js配置教程
Doodoo.js -- 中文最佳实践Node.js Web快速开发框架。支持Koa.js, Express.js中间件,支持模块化,插件,钩子机制,可以直接在项目里使用 ES6/7(Generator Function, Class, Async & Await)等特性 https://www.doodooke.com
配置
doodoo配置.env 文件位于项目根目录下,作为全局默认环境配置文件。
# 应用配置
APP_ROOT=app
APP_PORT=3000
APP_HOST=127.0.0.1
# MYSQL数据库链接
MYSQL=false
MYSQL_HOST=127.0.0.1
MYSQL_USER=root
MYSQL_PASSWORD=root
MYSQL_DATABASE=doodoo
MYSQL_PORT=3306
MYSQL_CHARSET=utf8mb4
# MONGODB数据库链接
MONGOOSE=false
MONGOOSE_URI=mongodb://127.0.0.1:27017/doodoo
# REDIS链接
REDIS=false
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PREFIX=doodoo:
# 静态资源服务
STATIC_DIR=www
STATIC_MAXAGE=30 * 24 * 60 * 60
STATIC_DYNAMIC=true
支持根据不同环境加载不同的配置文件(自定义文件配置将覆盖全局默认环境配置)
# 创建docker.env文件
touch docker.env
# 自定义docker环境启动
NODE_ENV=docker node app.js
Doodoo.js -- 中文最佳实践Node.js Web快速开发框架。支持Koa.js, Express.js中间件,支持模块化,插件,钩子机制,可以直接在项目里使用 ES6/7(Generator Function, Class, Async & Await)等特性 https://www.doodooke.com
配置
doodoo配置.env 文件位于项目根目录下,作为全局默认环境配置文件。
# 应用配置
APP_ROOT=app
APP_PORT=3000
APP_HOST=127.0.0.1
# MYSQL数据库链接
MYSQL=false
MYSQL_HOST=127.0.0.1
MYSQL_USER=root
MYSQL_PASSWORD=root
MYSQL_DATABASE=doodoo
MYSQL_PORT=3306
MYSQL_CHARSET=utf8mb4
# MONGODB数据库链接
MONGOOSE=false
MONGOOSE_URI=mongodb://127.0.0.1:27017/doodoo
# REDIS链接
REDIS=false
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PREFIX=doodoo:
# 静态资源服务
STATIC_DIR=www
STATIC_MAXAGE=30 * 24 * 60 * 60
STATIC_DYNAMIC=true
支持根据不同环境加载不同的配置文件(自定义文件配置将覆盖全局默认环境配置)
# 创建docker.env文件
touch docker.env
# 自定义docker环境启动
NODE_ENV=docker node app.js
收起阅读 »

doodoo.js快速入门教程
快速入门
我们通过3步演示如何快速创建一个doodoo项目
第一步
# 创建doodoo-demo目录
mkdir doodoo-demo && cd doodoo-demo
# 初始化npm
npm init -y
# 安装doodoo.js
yarn add doodooke/doodoo.js
# 创建app.js
touch app.js
接下来我们将以下代码copy到app.js
const Doodoo = require("doodoo.js");
const app = new Doodoo();
app.start();
第二步
# 创建app/hello/controller目录
mkdir -p app/hello/controller && cd app/hello/controller
# 创建test.js文件
touch test.js
接下来我们将以下代码copy到test.js
module.exports = class extends doodoo.Controller {
async _initialize() {
// 控制器初始化
console.log("_initialize");
}
async _before() {
// 控制器前置
console.log("_before");
}
async _before_index() {
// 方法前置
console.log("_before_index");
}
async index() {
console.log("index");
this.success("Hello Doodoo.js");
}
async _after_index() {
// 方法后置
console.log("_after_index");
}
async _after() {
// 控制器后置
console.log("_after");
}
};
第三步
进入doodoo-demo根目录
cd ../../../
启动项目
node app.js
通过命令行可以看到如下信息表示启动成功
[doodoo] Version: 1.0.3
[doodoo] Website: 127.0.0.1
[doodoo] Nodejs Version: v10.10.0
[doodoo] Nodejs Platform: darwin x64
[doodoo] Server Enviroment: development
[doodoo] Server Startup Time: 36ms
[doodoo] Server Current Time: 2018-10-09 20:26:40
[doodoo] Server Running At: http://127.0.0.1:3000
通过浏览器访问以下链接可以看到如下提示
http://127.0.0.1:3000/hello/test/index
{
errmsg: "ok",
errcode: 0,
data: "Hello Doodoo.js"
}
源码
按照传统,所有课程源代码基于 MIT 开源,托管于 GitHub :https://github.com/doodooke/doodoo-demo
快速入门
我们通过3步演示如何快速创建一个doodoo项目
第一步
# 创建doodoo-demo目录
mkdir doodoo-demo && cd doodoo-demo
# 初始化npm
npm init -y
# 安装doodoo.js
yarn add doodooke/doodoo.js
# 创建app.js
touch app.js
接下来我们将以下代码copy到app.js
const Doodoo = require("doodoo.js");
const app = new Doodoo();
app.start();
第二步
# 创建app/hello/controller目录
mkdir -p app/hello/controller && cd app/hello/controller
# 创建test.js文件
touch test.js
接下来我们将以下代码copy到test.js
module.exports = class extends doodoo.Controller {
async _initialize() {
// 控制器初始化
console.log("_initialize");
}
async _before() {
// 控制器前置
console.log("_before");
}
async _before_index() {
// 方法前置
console.log("_before_index");
}
async index() {
console.log("index");
this.success("Hello Doodoo.js");
}
async _after_index() {
// 方法后置
console.log("_after_index");
}
async _after() {
// 控制器后置
console.log("_after");
}
};
第三步
进入doodoo-demo根目录
cd ../../../
启动项目
node app.js
通过命令行可以看到如下信息表示启动成功
[doodoo] Version: 1.0.3
[doodoo] Website: 127.0.0.1
[doodoo] Nodejs Version: v10.10.0
[doodoo] Nodejs Platform: darwin x64
[doodoo] Server Enviroment: development
[doodoo] Server Startup Time: 36ms
[doodoo] Server Current Time: 2018-10-09 20:26:40
[doodoo] Server Running At: http://127.0.0.1:3000
通过浏览器访问以下链接可以看到如下提示
http://127.0.0.1:3000/hello/test/index
{
errmsg: "ok",
errcode: 0,
data: "Hello Doodoo.js"
}
源码
按照传统,所有课程源代码基于 MIT 开源,托管于 GitHub :https://github.com/doodooke/doodoo-demo

在web-view加载的本地及远程HTML中调用uni的API及网页和vue页面通讯
uni-app的web-view组件,支持加载远程网页,在app环境下,还支持加载本地HTML页面。
在web-view加载页面中,会涉及wx、plus、uni等对象的使用。
- 在小程序下使用wx的api,需要引入微信提供的https://res.wx.qq.com/open/js/jweixin-1.4.0.js。
- 在app下默认有plus对象,不需要引入js文件。
- 不管是在小程序下还是在app下,使用uni的api,需要引入https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.0.1.52.js
本文会详述在webview里的uni对象的使用方式,以及和vue页面的通讯方式。
HBuilderX 1.0.0 版本开始,uni-app 支持在 web-view 中调用 uni 的 API。
引用依赖的文件
在 web-view 加载的 HTML 中调用 uni 的 API,需要在 HTML 中引用必要的 JS-SDK。
<!-- 微信 JS-SDK 如果不需要兼容小程序,则无需引用此 JS 文件。 -->
<script type="text/javascript" src="//res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
<!-- uni 的 SDK,必须引用。 -->
<script type="text/javascript" src="//js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.0.1.52.js"></script>
Tips
- 这些 JS 文件是在 web-view 加载的那个 HTML 文件中引用的,而不是 uni-app 项目中的文件。
- 如果不考虑微信小程序,则无需引入微信的 JS-SDK。
- 两个文件同时引入时,注意引入的顺序,微信的需要在前。
调用的时机
在引用依赖的文件后,需要在 HTML 中监听 UniAppJSBridgeReady 事件触发后,才能安全调用 uni 的 API。
document.addEventListener('UniAppJSBridgeReady', function() {
uni.getEnv(function(res) {
console.log('当前环境:' + JSON.stringify(res));
});
});
页面跳转
支持调用所有的 uni 路由方法,可以实现从 HTML 重新跳转回应用内的页面。
在 UniAppJSBridgeReady 后,调用路由方法跳转到应用内的页面。
document.addEventListener('UniAppJSBridgeReady', function() {
document.querySelector('.btn-list').addEventListener('click', function(evt) {
var target = evt.target;
if (target.tagName === 'BUTTON') {
var action = target.getAttribute('data-action');
if(action === 'navigateTo') {
uni.navigateTo({
url: '/pages/component/button/button'
});
}
}
});
});
发送消息
可以通过 uni.postMessage 在 HTML 中向应用发送消息。要实现此功能,需要完成以下两步工作。
监听 web-view 的 message 事件
监听 web-view 组件的 message 事件,然后在事件回调的 event.detail.data 中接收传递过来的消息。
<template>
<view>
<web-view src="http://192.168.1.1:3000/test.html" @message="handleMessage"></web-view>
</view>
</template>
<script>
export default {
methods: {
handleMessage(evt) {
console.log('接收到的消息:' + JSON.stringify(evt.detail.data));
}
}
}
</script>
从 HTML 向应用发送消息
uni.postMessage 中的参数格式,必须是 data: {}。也就是说,传递的消息信息必须在 data 这个对象中。
document.addEventListener('UniAppJSBridgeReady', function() {
uni.postMessage({
data: {
action: 'postMessage'
}
});
});
每次执行 postMessage 后,传递的消息会以数组的形式存放。因此,在 web-view 的 message 事件回调中,接收到的 event.detail.data 的值是一个数组。
获取当前环境信息
HTML 在不同的环境下,可能需要执行不同的操作或传递不同的消息。可以通过 uni.getEnv() 方法,来获取当前的环境信息。
document.addEventListener('UniAppJSBridgeReady', function() {
uni.getEnv(function(res) {
if (res.plus) {
console.log('当前环境为【5+App】');
} else if (res.miniprogram) {
console.log('当前环境为【微信小程序】');
}
});
});
本地 HTML
自 HBuilderX v1.1.0 起,在 5+App 平台下 web-view 支持加载应用内的 HTML 资源。
本地的 HTML 资源,必须存放在规定的目录下,即 uni-app 项目->hybrid->html 目录。
├─common
├─components
├─hybrid
│ └─html
│ test.html
├─pages
├─static
│ App.vue
│ main.js
│ manifest.json
│ pages.json
与 html 文件相关的 css、js 等本地资源,同样放在这个 hybrid->html 目录下。
这个hybrid目录不会被编译器编译,所以这里的不能放vue文件,而其他目录也不能放本地HTML文件。
未来hybrid目录还会支持其他语言在uni-app的中的混合使用。
注意:在本地 HTML 中引入网络资源时,必须补全协议。比如:https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.0.1.52.js
运行体验
示例中 web-view 加载的是一个本机的测试地址,这个测试 HTML 见附件。
-
加载网络地址的话,需要在本机启动一个服务将此 HTML 放进去,然后修改 hello uni-app 中的 web-view 例子的 src 地址为可访问的局域网地址。
-
如果是加载本地 HTML 的话,就直接新建目录将此 HTML 放进去,然后修改 web-view 的 src 为 /hybrid/html/test.html 即可。
-
参考文档:web-view
web-view组件在app中的窗体关系和plus.webview操作方式
uni-app的vue页面本身是一个webview,vue页面里的web-view组件,其实是一个子webview。
但一个vue页面不能放多个web-view组件,这个组件默认是全屏的(不会覆盖原生头和原生导航)。
使用plus代码获得当前webview的对象后(参考此文https://ask.dcloud.net.cn/article/35036),再获取子webview,其实也可以得到web-view组件所对应的plus的webview对象,进而再使用plus.webview的丰富api。
获取子webview时注意时机,获取方法执行太早可能获取不到。
uni-app的web-view组件,支持加载远程网页,在app环境下,还支持加载本地HTML页面。
在web-view加载页面中,会涉及wx、plus、uni等对象的使用。
- 在小程序下使用wx的api,需要引入微信提供的https://res.wx.qq.com/open/js/jweixin-1.4.0.js。
- 在app下默认有plus对象,不需要引入js文件。
- 不管是在小程序下还是在app下,使用uni的api,需要引入https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.0.1.52.js
本文会详述在webview里的uni对象的使用方式,以及和vue页面的通讯方式。
HBuilderX 1.0.0 版本开始,uni-app 支持在 web-view 中调用 uni 的 API。
引用依赖的文件
在 web-view 加载的 HTML 中调用 uni 的 API,需要在 HTML 中引用必要的 JS-SDK。
<!-- 微信 JS-SDK 如果不需要兼容小程序,则无需引用此 JS 文件。 -->
<script type="text/javascript" src="//res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
<!-- uni 的 SDK,必须引用。 -->
<script type="text/javascript" src="//js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.0.1.52.js"></script>
Tips
- 这些 JS 文件是在 web-view 加载的那个 HTML 文件中引用的,而不是 uni-app 项目中的文件。
- 如果不考虑微信小程序,则无需引入微信的 JS-SDK。
- 两个文件同时引入时,注意引入的顺序,微信的需要在前。
调用的时机
在引用依赖的文件后,需要在 HTML 中监听 UniAppJSBridgeReady 事件触发后,才能安全调用 uni 的 API。
document.addEventListener('UniAppJSBridgeReady', function() {
uni.getEnv(function(res) {
console.log('当前环境:' + JSON.stringify(res));
});
});
页面跳转
支持调用所有的 uni 路由方法,可以实现从 HTML 重新跳转回应用内的页面。
在 UniAppJSBridgeReady 后,调用路由方法跳转到应用内的页面。
document.addEventListener('UniAppJSBridgeReady', function() {
document.querySelector('.btn-list').addEventListener('click', function(evt) {
var target = evt.target;
if (target.tagName === 'BUTTON') {
var action = target.getAttribute('data-action');
if(action === 'navigateTo') {
uni.navigateTo({
url: '/pages/component/button/button'
});
}
}
});
});
发送消息
可以通过 uni.postMessage 在 HTML 中向应用发送消息。要实现此功能,需要完成以下两步工作。
监听 web-view 的 message 事件
监听 web-view 组件的 message 事件,然后在事件回调的 event.detail.data 中接收传递过来的消息。
<template>
<view>
<web-view src="http://192.168.1.1:3000/test.html" @message="handleMessage"></web-view>
</view>
</template>
<script>
export default {
methods: {
handleMessage(evt) {
console.log('接收到的消息:' + JSON.stringify(evt.detail.data));
}
}
}
</script>
从 HTML 向应用发送消息
uni.postMessage 中的参数格式,必须是 data: {}。也就是说,传递的消息信息必须在 data 这个对象中。
document.addEventListener('UniAppJSBridgeReady', function() {
uni.postMessage({
data: {
action: 'postMessage'
}
});
});
每次执行 postMessage 后,传递的消息会以数组的形式存放。因此,在 web-view 的 message 事件回调中,接收到的 event.detail.data 的值是一个数组。
获取当前环境信息
HTML 在不同的环境下,可能需要执行不同的操作或传递不同的消息。可以通过 uni.getEnv() 方法,来获取当前的环境信息。
document.addEventListener('UniAppJSBridgeReady', function() {
uni.getEnv(function(res) {
if (res.plus) {
console.log('当前环境为【5+App】');
} else if (res.miniprogram) {
console.log('当前环境为【微信小程序】');
}
});
});
本地 HTML
自 HBuilderX v1.1.0 起,在 5+App 平台下 web-view 支持加载应用内的 HTML 资源。
本地的 HTML 资源,必须存放在规定的目录下,即 uni-app 项目->hybrid->html 目录。
├─common
├─components
├─hybrid
│ └─html
│ test.html
├─pages
├─static
│ App.vue
│ main.js
│ manifest.json
│ pages.json
与 html 文件相关的 css、js 等本地资源,同样放在这个 hybrid->html 目录下。
这个hybrid目录不会被编译器编译,所以这里的不能放vue文件,而其他目录也不能放本地HTML文件。
未来hybrid目录还会支持其他语言在uni-app的中的混合使用。
注意:在本地 HTML 中引入网络资源时,必须补全协议。比如:https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.0.1.52.js
运行体验
示例中 web-view 加载的是一个本机的测试地址,这个测试 HTML 见附件。
-
加载网络地址的话,需要在本机启动一个服务将此 HTML 放进去,然后修改 hello uni-app 中的 web-view 例子的 src 地址为可访问的局域网地址。
-
如果是加载本地 HTML 的话,就直接新建目录将此 HTML 放进去,然后修改 web-view 的 src 为 /hybrid/html/test.html 即可。
-
参考文档:web-view
web-view组件在app中的窗体关系和plus.webview操作方式
uni-app的vue页面本身是一个webview,vue页面里的web-view组件,其实是一个子webview。
但一个vue页面不能放多个web-view组件,这个组件默认是全屏的(不会覆盖原生头和原生导航)。
使用plus代码获得当前webview的对象后(参考此文https://ask.dcloud.net.cn/article/35036),再获取子webview,其实也可以得到web-view组件所对应的plus的webview对象,进而再使用plus.webview的丰富api。
获取子webview时注意时机,获取方法执行太早可能获取不到。

移动端 H5 场景应用【破茧成蝶】案例鉴赏
移动端【破茧成蝶】场景请用微信扫描二维码访问(温馨提示:H5案例有声音,请打开声音体验):

案例:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
<meta name="viewport" content="width=640, user-scalable=no,target-densityDpi=device-dpi">
<style>
*{ margin:0; padding:0;}
html{ overflow:hidden;}
li{ list-style:none;}
#main{ width:640px; height:auto; position:relative; overflow:hidden;}
#c1{ width:100%; height:100%; position:absolute; left:0; top:0; z-index:10;}
#list{}
#list > li{ width:100%; height:100%; background-repeat:no-repeat; position:absolute; left:0; top:0; background-size:cover; z-index:5; display:none;}
#list > li.zIndex{ z-index:6;}
#list > li:nth-of-type(1){ background-image:url(img/b.png); display:block;}
#list > li:nth-of-type(2){ background-image:url(img/c.png);}
#list > li:nth-of-type(3){ background-image:url(img/d.png);}
#list > li:nth-of-type(4){ background-image:url(img/e.png);}
#list > li:nth-of-type(5){ background-image:url(img/ad1.png);}
#list > li:nth-of-type(6){ background-image:url(img/ad2.png);}
#list > li:nth-of-type(7){ background-image:url(img/ad3.png);}
#list > li:nth-of-type(8){ background-image:url(img/ad4.png);}
</style>
<script src="jquery-2.1.3.min.js"></script>
<script>
$(document).on('touchmove',function(ev){
ev.preventDefault();
});
$(function(){
var $main = $('#main');
var $list = $('#list');
var $li = $list.find('>li');
var viewHeight = $(window).height();
$main.css('height',viewHeight);
slideCanvas();
slideImg();
function slideCanvas(){
var $c = $('#c1');
var gc = $c.get(0).getContext('2d');
var img = new Image();
var bBtn = true;
$c.attr('height',viewHeight);
img.src = 'img/a.png';
img.onload = function(){
gc.drawImage(img,(640 - nowViewWidth())/2,0,nowViewWidth(),viewHeight);
gc.strokeStyle = 'blue';
gc.lineWidth = 60;
gc.lineCap = 'round';
gc.globalCompositeOperation = 'destination-out';
$c.on('touchstart',function(ev){
var touch = ev.originalEvent.changedTouches[0];
var x = touch.pageX - $(this).offset().left;
var y = touch.pageY - $(this).offset().top;
/*gc.arc(x,y,100,0,360*Math.PI/180);
gc.fill();*/
if(bBtn){
bBtn = false;
gc.moveTo(x,y);
gc.lineTo(x+1,y+1);
}
else{
gc.lineTo(x,y);
}
gc.stroke();
$c.on('touchmove.move',function(ev){
var touch = ev.originalEvent.changedTouches[0];
var x = touch.pageX - $(this).offset().left;
var y = touch.pageY - $(this).offset().top;
gc.lineTo(x,y);
gc.stroke();
});
$c.on('touchend.move',function(ev){
var imgData = gc.getImageData(0,0,640,viewHeight);
var allPx = imgData.width * imgData.height;
var num = 0;
for(var i=0;i<allPx;i++){
if( imgData.data[4*i+3] == 0 ){
num++;
}
}
if( num > allPx/2 ){
$c.animate({opacity:0},1000,function(){
$(this).remove();
});
}
$c.off('.move');
});
});
};
}
function slideImg(){
var startY = 0;
var step = 1/4;
var nowIndex = 0;
var nextorprevIndex = 0;
var bBtn = true;
$li.css('backgroundPosition', (640 - nowViewWidth())/2 +'px 0');
$li.on('touchstart',function(ev){
if(bBtn){
bBtn = false;
var touch = ev.originalEvent.changedTouches[0];
startY = touch.pageY;
nowIndex = $(this).index();
$li.on('touchmove.move',function(ev){
var touch = ev.originalEvent.changedTouches[0];
$(this).siblings().hide();
if( touch.pageY < startY ){ //↑
nextorprevIndex = nowIndex == $li.length-1 ? 0 : nowIndex + 1;
$li.eq(nextorprevIndex).css('transform','translate(0,'+( viewHeight + touch.pageY - startY )+'px)');
}
else{ //↓
nextorprevIndex = nowIndex == 0 ? $li.length-1 : nowIndex - 1;
$li.eq(nextorprevIndex).css('transform','translate(0,'+( -viewHeight + touch.pageY - startY )+'px)');
}
$li.eq(nextorprevIndex).show().addClass('zIndex');
//Math.abs((touch.pageY - startY))/viewHeight -> 最大值 -viewHeight~viewHeight
$(this).css('transform','translate(0,'+ (touch.pageY - startY)*step +'px) scale('+(1 - Math.abs((touch.pageY - startY))*step/viewHeight )+')');
});
$li.on('touchend.move',function(ev){
var touch = ev.originalEvent.changedTouches[0];
if( touch.pageY < startY ){ //↑
$li.eq(nowIndex).css('transform','translate(0,'+(-viewHeight * step)+'px) scale('+(1 - step)+')');
}
else{ //↓
$li.eq(nowIndex).css('transform','translate(0,'+(viewHeight * step)+'px) scale('+(1 - step)+')');
}
$li.eq(nowIndex).css('transition','.3s');
$li.eq(nextorprevIndex).css('transform','translate(0,0)');
$li.eq(nextorprevIndex).css('transition','.3s');
$li.off('.move');
});
}
});
$li.on('transitionEnd webkitTransitionEnd',function(){
resetFn();
});
function resetFn(){
$li.css('transform','');
$li.css('transition','');
$li.eq(nextorprevIndex).removeClass('zIndex').siblings().hide();
bBtn = true;
}
}
function nowViewWidth(){
var w = 640 * viewHeight / 960;
w = w > 640 ? w : 640;
return w;
}
});
</script>
</head>
<body>
<div id="main">
<canvas id="c1" width="640" height="960"></canvas>
<ul id="list">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
</body>
</html>
一、什么是微信场景应用
三、场景运行环境
1) 微信内嵌的浏览器
2) Chrome自带移动端Emulation(模拟器)
四、场景一功能
1) 加载,刮开,划屏,动画,音乐等
五、jQuery
1) 版本2.1.3
六、手机分辨率
1) 屏幕
2) 设备
七、主流屏幕分辨率
1) 640 960
2) 640 1136
八、viewport
1) 默认视口
2) width=device-width , user-scalable=no
3) target-densityDpi=device-dpi
4) 固定值640即可
九、设置高度
1) 通过JS动态设置
2) background-size : cover
十、刮开效果
1) canvas
2) globalCompositeOperation
a. source-over
b. destination-over
c. destination-out
十一、移动端事件
1) touchstart
2) touchmove
3) touchend
4) 原生event
a. originalEvent
b. changedTouches
5) 阻止默认touchmove
a. preventDefault
十二、划屏切换
1) css3
2) 运动实现
3) transform
a. translate
b. scale
c. transition
d. transitionEnd事件
十三、提示箭头
1) css3
a. animation
b. 名字
c. 时间
d. 执行次数
e. infinite
2) @keyframes
a. 帧
十四、入场动画
1) 文字样式
2) css3+js
a. transform
b. transition
3) 图标
a. 可以用图片
b. 也可以用字体库,Font Awesome
十五、音乐
1) audio
a. play()
b. pause()
十六、加载
1) css3
2) 控制scale
3) animation-delay
4) js
5) new Image
十七、查看场景二效果
1) 声音,音乐,加载,3D魔方,3D划屏,粒子操作
十八、适配
1) 第二种模式方案
十九、音乐
1) audio
2) play()
3) pause()
二十、3D魔方
1) perspective
2) preserve-3d
3) transform-origin
二十一、3D划屏
1) translateZ
二十二、粒子操作
1) canvas像素级操作
2) canvas运动模式
二十三、加载
1) linear-gradient
移动端【破茧成蝶】场景请用微信扫描二维码访问(温馨提示:H5案例有声音,请打开声音体验):
案例:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>无标题文档</title>
<meta name="viewport" content="width=640, user-scalable=no,target-densityDpi=device-dpi">
<style>
*{ margin:0; padding:0;}
html{ overflow:hidden;}
li{ list-style:none;}
#main{ width:640px; height:auto; position:relative; overflow:hidden;}
#c1{ width:100%; height:100%; position:absolute; left:0; top:0; z-index:10;}
#list{}
#list > li{ width:100%; height:100%; background-repeat:no-repeat; position:absolute; left:0; top:0; background-size:cover; z-index:5; display:none;}
#list > li.zIndex{ z-index:6;}
#list > li:nth-of-type(1){ background-image:url(img/b.png); display:block;}
#list > li:nth-of-type(2){ background-image:url(img/c.png);}
#list > li:nth-of-type(3){ background-image:url(img/d.png);}
#list > li:nth-of-type(4){ background-image:url(img/e.png);}
#list > li:nth-of-type(5){ background-image:url(img/ad1.png);}
#list > li:nth-of-type(6){ background-image:url(img/ad2.png);}
#list > li:nth-of-type(7){ background-image:url(img/ad3.png);}
#list > li:nth-of-type(8){ background-image:url(img/ad4.png);}
</style>
<script src="jquery-2.1.3.min.js"></script>
<script>
$(document).on('touchmove',function(ev){
ev.preventDefault();
});
$(function(){
var $main = $('#main');
var $list = $('#list');
var $li = $list.find('>li');
var viewHeight = $(window).height();
$main.css('height',viewHeight);
slideCanvas();
slideImg();
function slideCanvas(){
var $c = $('#c1');
var gc = $c.get(0).getContext('2d');
var img = new Image();
var bBtn = true;
$c.attr('height',viewHeight);
img.src = 'img/a.png';
img.onload = function(){
gc.drawImage(img,(640 - nowViewWidth())/2,0,nowViewWidth(),viewHeight);
gc.strokeStyle = 'blue';
gc.lineWidth = 60;
gc.lineCap = 'round';
gc.globalCompositeOperation = 'destination-out';
$c.on('touchstart',function(ev){
var touch = ev.originalEvent.changedTouches[0];
var x = touch.pageX - $(this).offset().left;
var y = touch.pageY - $(this).offset().top;
/*gc.arc(x,y,100,0,360*Math.PI/180);
gc.fill();*/
if(bBtn){
bBtn = false;
gc.moveTo(x,y);
gc.lineTo(x+1,y+1);
}
else{
gc.lineTo(x,y);
}
gc.stroke();
$c.on('touchmove.move',function(ev){
var touch = ev.originalEvent.changedTouches[0];
var x = touch.pageX - $(this).offset().left;
var y = touch.pageY - $(this).offset().top;
gc.lineTo(x,y);
gc.stroke();
});
$c.on('touchend.move',function(ev){
var imgData = gc.getImageData(0,0,640,viewHeight);
var allPx = imgData.width * imgData.height;
var num = 0;
for(var i=0;i<allPx;i++){
if( imgData.data[4*i+3] == 0 ){
num++;
}
}
if( num > allPx/2 ){
$c.animate({opacity:0},1000,function(){
$(this).remove();
});
}
$c.off('.move');
});
});
};
}
function slideImg(){
var startY = 0;
var step = 1/4;
var nowIndex = 0;
var nextorprevIndex = 0;
var bBtn = true;
$li.css('backgroundPosition', (640 - nowViewWidth())/2 +'px 0');
$li.on('touchstart',function(ev){
if(bBtn){
bBtn = false;
var touch = ev.originalEvent.changedTouches[0];
startY = touch.pageY;
nowIndex = $(this).index();
$li.on('touchmove.move',function(ev){
var touch = ev.originalEvent.changedTouches[0];
$(this).siblings().hide();
if( touch.pageY < startY ){ //↑
nextorprevIndex = nowIndex == $li.length-1 ? 0 : nowIndex + 1;
$li.eq(nextorprevIndex).css('transform','translate(0,'+( viewHeight + touch.pageY - startY )+'px)');
}
else{ //↓
nextorprevIndex = nowIndex == 0 ? $li.length-1 : nowIndex - 1;
$li.eq(nextorprevIndex).css('transform','translate(0,'+( -viewHeight + touch.pageY - startY )+'px)');
}
$li.eq(nextorprevIndex).show().addClass('zIndex');
//Math.abs((touch.pageY - startY))/viewHeight -> 最大值 -viewHeight~viewHeight
$(this).css('transform','translate(0,'+ (touch.pageY - startY)*step +'px) scale('+(1 - Math.abs((touch.pageY - startY))*step/viewHeight )+')');
});
$li.on('touchend.move',function(ev){
var touch = ev.originalEvent.changedTouches[0];
if( touch.pageY < startY ){ //↑
$li.eq(nowIndex).css('transform','translate(0,'+(-viewHeight * step)+'px) scale('+(1 - step)+')');
}
else{ //↓
$li.eq(nowIndex).css('transform','translate(0,'+(viewHeight * step)+'px) scale('+(1 - step)+')');
}
$li.eq(nowIndex).css('transition','.3s');
$li.eq(nextorprevIndex).css('transform','translate(0,0)');
$li.eq(nextorprevIndex).css('transition','.3s');
$li.off('.move');
});
}
});
$li.on('transitionEnd webkitTransitionEnd',function(){
resetFn();
});
function resetFn(){
$li.css('transform','');
$li.css('transition','');
$li.eq(nextorprevIndex).removeClass('zIndex').siblings().hide();
bBtn = true;
}
}
function nowViewWidth(){
var w = 640 * viewHeight / 960;
w = w > 640 ? w : 640;
return w;
}
});
</script>
</head>
<body>
<div id="main">
<canvas id="c1" width="640" height="960"></canvas>
<ul id="list">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
</body>
</html>
一、什么是微信场景应用
三、场景运行环境
1) 微信内嵌的浏览器
2) Chrome自带移动端Emulation(模拟器)
四、场景一功能
1) 加载,刮开,划屏,动画,音乐等
五、jQuery
1) 版本2.1.3
六、手机分辨率
1) 屏幕
2) 设备
七、主流屏幕分辨率
1) 640 960
2) 640 1136
八、viewport
1) 默认视口
2) width=device-width , user-scalable=no
3) target-densityDpi=device-dpi
4) 固定值640即可
九、设置高度
1) 通过JS动态设置
2) background-size : cover
十、刮开效果
1) canvas
2) globalCompositeOperation
a. source-over
b. destination-over
c. destination-out
十一、移动端事件
1) touchstart
2) touchmove
3) touchend
4) 原生event
a. originalEvent
b. changedTouches
5) 阻止默认touchmove
a. preventDefault
十二、划屏切换
1) css3
2) 运动实现
3) transform
a. translate
b. scale
c. transition
d. transitionEnd事件
十三、提示箭头
1) css3
a. animation
b. 名字
c. 时间
d. 执行次数
e. infinite
2) @keyframes
a. 帧
十四、入场动画
1) 文字样式
2) css3+js
a. transform
b. transition
3) 图标
a. 可以用图片
b. 也可以用字体库,Font Awesome
十五、音乐
1) audio
a. play()
b. pause()
十六、加载
1) css3
2) 控制scale
3) animation-delay
4) js
5) new Image
十七、查看场景二效果
1) 声音,音乐,加载,3D魔方,3D划屏,粒子操作
十八、适配
1) 第二种模式方案
十九、音乐
1) audio
2) play()
3) pause()
二十、3D魔方
1) perspective
2) preserve-3d
3) transform-origin
二十一、3D划屏
1) translateZ
二十二、粒子操作
1) canvas像素级操作
2) canvas运动模式
二十三、加载
1) linear-gradient

HTML编程之利用jquery制作长图动画的方法
在网站前端编程开发中,我们经常会遇到需要将图片设置为背景图,当鼠标移入时利用setTimeout定时器去控制改变background-position使得图片逐帧向上移动,鼠标移除则控制向下移动,但要注意在鼠标移入和移出时要相互关闭定时器。具体如何来实现呢?下面就来为各位分析解答一下吧。
var positionC=['0','-75','-150','-225','-300','-375','-450','-525','-600','-675','-750','-825','-900','-975','-1050','-1125','-1200','-1275','-1350','-1425','-1500','-1575','-1650',"-1800"];
// var positionC=['0','-180','-360','-540','-720','-900','-1080','-1260','-1440','-1620','-1500','-1650',"-1800",];
var iconC=0;
var t1;
var i1;
$(".bgk1").mousemove(function () {
clearTimeout(i1);
iconABC();
})
$(".bgk1").mouseout(function () {
iconBC();
})
function iconABC(){
$(".bgk1").css("background-position" , 0+"px "+positionC[iconC]+"px");
iconC++;
if(iconC>positionC.length){
iconC=positionC.length;
return;
}
t1=setTimeout(iconABC,80);
console.log("sdd"+iconC)
}
function iconBC(){
clearTimeout(t1);
iconC--;
if(iconC<0){
iconC=0;
return;
}
$(".bgk1").css("background-position" , 0+"px "+positionC[iconC]+"px");
i1=setTimeout(iconBC,20);
console.log("--"+iconC)
}
好了,现在是不是就可以实现了呢?如果大家还是存在不理解的地方,或者总是有出错的地方,都是可以留言咨询的。
本文由专业的郑州app开发公司燚轩科技整理发布,原创不易,如需转载请注明出处。
在网站前端编程开发中,我们经常会遇到需要将图片设置为背景图,当鼠标移入时利用setTimeout定时器去控制改变background-position使得图片逐帧向上移动,鼠标移除则控制向下移动,但要注意在鼠标移入和移出时要相互关闭定时器。具体如何来实现呢?下面就来为各位分析解答一下吧。
var positionC=['0','-75','-150','-225','-300','-375','-450','-525','-600','-675','-750','-825','-900','-975','-1050','-1125','-1200','-1275','-1350','-1425','-1500','-1575','-1650',"-1800"];
// var positionC=['0','-180','-360','-540','-720','-900','-1080','-1260','-1440','-1620','-1500','-1650',"-1800",];
var iconC=0;
var t1;
var i1;
$(".bgk1").mousemove(function () {
clearTimeout(i1);
iconABC();
})
$(".bgk1").mouseout(function () {
iconBC();
})
function iconABC(){
$(".bgk1").css("background-position" , 0+"px "+positionC[iconC]+"px");
iconC++;
if(iconC>positionC.length){
iconC=positionC.length;
return;
}
t1=setTimeout(iconABC,80);
console.log("sdd"+iconC)
}
function iconBC(){
clearTimeout(t1);
iconC--;
if(iconC<0){
iconC=0;
return;
}
$(".bgk1").css("background-position" , 0+"px "+positionC[iconC]+"px");
i1=setTimeout(iconBC,20);
console.log("--"+iconC)
}
好了,现在是不是就可以实现了呢?如果大家还是存在不理解的地方,或者总是有出错的地方,都是可以留言咨询的。
本文由专业的郑州app开发公司燚轩科技整理发布,原创不易,如需转载请注明出处。
收起阅读 »
下拉刷新列表及与后台交互demo
之前是一次性加载所有数据,最近研究了下拉刷新分页展示。期间踩的坑 哎 不说了 直接发demo
请求后台接口改成自己的即可,
<div class="mui-content" style="margin-top:2.5rem;">
<div>
<div id="item1" class="mui-control-content mui-active">
<div id="scroll" class="mui-scroll-wrapper">
<div id="pullrefresh" class="mui-scroll">
<ul class="mui-table-view">
<!--数据展示区-->
</ul>
</div>
</div>
</div>
</div>
</div>
mui.init({
swipeBack:true, //启用右滑关闭功能
pullRefresh: {
container: '#pullrefresh',
down:{
auto:true,
contentrefresh: '',
style:'circle',
callback: pulldownRefresh
}
}
});
var count = 0;
var isOver = false;//是否加载完
function addData() {
var userid = localStorage.getItem('Userid');
var pageSize = 10;//条数
var Limit = count*pageSize;
mui.ajax(serverhost+'/getmyfeedback/myfeedbacklist',{
data:{pageStart:Limit,userid},
dataType:'json',
type:'GET',
timeout:5000,
success:function(res){
if(res.return_code==0){
var data = res.data;
var table = document.body.querySelector('.mui-table-view');
for (var i=0;i< data.length;i++) {
if(data[i].text ==''){
data[i].text = '问题确认中';
}
var li = document.createElement('li');
li.className = 'mui-table-view-cell';
li.innerHTML = '<h5>'+data[i].title+'</h5>'+
'<h5>'+data[i].ftext+'</h5>'+
'<p style="color:red;font-weight:bold;">'+data[i].text+'</p>';
//下拉刷新,纪录插入;
table.insertBefore(li, table.firstChild);
}
if(data.length < pageSize){
isOver = true;
}else{
count++;
}
}
},error: function(xhr, type, errorThrown) {
mui.toast('网络异常,请稍后再试');
}
})
}
/**
- 下拉刷新具体业务实现
*/
function pulldownRefresh() {
setTimeout(function() {
if(isOver == true){
mui.toast("我是有底线滴~");
mui('#pullrefresh').pullRefresh().endPulldown((isOver));
return false;
}else{
addData();
mui('#pullrefresh').pullRefresh().endPulldown((isOver));
}
},800);
}
之前是一次性加载所有数据,最近研究了下拉刷新分页展示。期间踩的坑 哎 不说了 直接发demo
请求后台接口改成自己的即可,
<div class="mui-content" style="margin-top:2.5rem;">
<div>
<div id="item1" class="mui-control-content mui-active">
<div id="scroll" class="mui-scroll-wrapper">
<div id="pullrefresh" class="mui-scroll">
<ul class="mui-table-view">
<!--数据展示区-->
</ul>
</div>
</div>
</div>
</div>
</div>
mui.init({
swipeBack:true, //启用右滑关闭功能
pullRefresh: {
container: '#pullrefresh',
down:{
auto:true,
contentrefresh: '',
style:'circle',
callback: pulldownRefresh
}
}
});
var count = 0;
var isOver = false;//是否加载完
function addData() {
var userid = localStorage.getItem('Userid');
var pageSize = 10;//条数
var Limit = count*pageSize;
mui.ajax(serverhost+'/getmyfeedback/myfeedbacklist',{
data:{pageStart:Limit,userid},
dataType:'json',
type:'GET',
timeout:5000,
success:function(res){
if(res.return_code==0){
var data = res.data;
var table = document.body.querySelector('.mui-table-view');
for (var i=0;i< data.length;i++) {
if(data[i].text ==''){
data[i].text = '问题确认中';
}
var li = document.createElement('li');
li.className = 'mui-table-view-cell';
li.innerHTML = '<h5>'+data[i].title+'</h5>'+
'<h5>'+data[i].ftext+'</h5>'+
'<p style="color:red;font-weight:bold;">'+data[i].text+'</p>';
//下拉刷新,纪录插入;
table.insertBefore(li, table.firstChild);
}
if(data.length < pageSize){
isOver = true;
}else{
count++;
}
}
},error: function(xhr, type, errorThrown) {
mui.toast('网络异常,请稍后再试');
}
})
}
/**
- 下拉刷新具体业务实现
*/
function pulldownRefresh() {
setTimeout(function() {
if(isOver == true){
mui.toast("我是有底线滴~");
mui('#pullrefresh').pullRefresh().endPulldown((isOver));
return false;
}else{
addData();
mui('#pullrefresh').pullRefresh().endPulldown((isOver));
}
},800);
}

一周 D 报(2018-10-08)
结束了一周为祖国母亲庆生的活动,各位同学陆续回到各自的岗位开始了新的一周工(摸)作(鱼)。
热门话题
近期最热门的话题,当属 uni-app 无疑。
- uni-app 什么时候支持离线(本地)打包?相关工作已经初步完成,详见:HTML5+ SDK 中的说明。
- uni-app 是否支持 npm 直接安装第三方包?本周更新的 HBuilderX 中,包含了此重大功能。参考文档:NPM支持。
- uni-app 是否支持热更新?相关的工作已经在计划中,鉴于目前重点工作是框架的稳定以及完善,待稳定后诸如此类工作开展起来就方便许多,还望各位同学能够理解。
- 云端打包怎么又排队了。伴随着 uni-app 的发布及用户的持续增长,每日打包的人数也随着增长。尤其是周四周五,是打包的高峰,排队不可避免地就出现了。如果出现排队的情况,请大家不要惊慌,耐心等待即可。我们也在不断做优化,以期给大家提供更加优质的服务。
uni-app & iOS
- uni-app内置了vuex,使用的时候改怎么使用:社区单独有一篇文章简述了使用方法,并且登录模板示例中也有更加具体的用法。
- uni-app navigator中参数要如何绑定:在 uni-app 中需要使用 Vue 的规范在模板属性上绑定数据,这位同学的情况是熟悉小程序的开发规范,可能对于 Vue 的不太熟悉。
- 获取APP的版本信息Version不正确:uni.getSystemInfo 中获取的 version 是引擎的版本号,而非应用自身的版本,之前的文档描述有误已经修复。获取应用的版本号,需要调用 plus.runtime.version。
- 图像/文件本地保存路径不正确:本周更新修复,unifile:// 协议将会取消,直接返回各平台原始的值。
- 请问下如何限制只能ios10及以上才能运行呢?:manifest.json 中可以进行配置,详见回复。
- IOS审核因为定位权限被拒绝:老问题了,获取定位权限的描述,一定要写清楚具体的业务行为,而不是笼统地说我要获取定位在应用里面用。
- 关于 iOS12 的更新,新系统的一些适配工作也在不停地进行,如果大家遇到问题,请及时向我们反馈。
开源与分享
- uniapp自定义底部导航,带凸起 @七月_
- swiper + scroll-view 实现下拉刷新 @杨大宝
- uni-app全局变量的几种实现方式:内置 vuex 的简单使用,示例中也有演示。
- uni-app中类似mui中的chat、im(聊天窗口)实现 @xcecd@qq.com
- UNI-Chat [不支持打包小程序] 简单配置 实现即时通讯 @健健
- HBuilder X对vue的支持有多强?:极致的 Vue 开发体验,就在 HBuilderX。
- 环信IM SDK 移植分享 @诗小柒
更多分享,请前往 精华区 查看。
欢迎更多的同学参与进来,分享自己的经验心得。
结束
本期周报就到这里,感谢大家的阅读。新的一周,祝大家工作顺利。
结束了一周为祖国母亲庆生的活动,各位同学陆续回到各自的岗位开始了新的一周工(摸)作(鱼)。
热门话题
近期最热门的话题,当属 uni-app 无疑。
- uni-app 什么时候支持离线(本地)打包?相关工作已经初步完成,详见:HTML5+ SDK 中的说明。
- uni-app 是否支持 npm 直接安装第三方包?本周更新的 HBuilderX 中,包含了此重大功能。参考文档:NPM支持。
- uni-app 是否支持热更新?相关的工作已经在计划中,鉴于目前重点工作是框架的稳定以及完善,待稳定后诸如此类工作开展起来就方便许多,还望各位同学能够理解。
- 云端打包怎么又排队了。伴随着 uni-app 的发布及用户的持续增长,每日打包的人数也随着增长。尤其是周四周五,是打包的高峰,排队不可避免地就出现了。如果出现排队的情况,请大家不要惊慌,耐心等待即可。我们也在不断做优化,以期给大家提供更加优质的服务。
uni-app & iOS
- uni-app内置了vuex,使用的时候改怎么使用:社区单独有一篇文章简述了使用方法,并且登录模板示例中也有更加具体的用法。
- uni-app navigator中参数要如何绑定:在 uni-app 中需要使用 Vue 的规范在模板属性上绑定数据,这位同学的情况是熟悉小程序的开发规范,可能对于 Vue 的不太熟悉。
- 获取APP的版本信息Version不正确:uni.getSystemInfo 中获取的 version 是引擎的版本号,而非应用自身的版本,之前的文档描述有误已经修复。获取应用的版本号,需要调用 plus.runtime.version。
- 图像/文件本地保存路径不正确:本周更新修复,unifile:// 协议将会取消,直接返回各平台原始的值。
- 请问下如何限制只能ios10及以上才能运行呢?:manifest.json 中可以进行配置,详见回复。
- IOS审核因为定位权限被拒绝:老问题了,获取定位权限的描述,一定要写清楚具体的业务行为,而不是笼统地说我要获取定位在应用里面用。
- 关于 iOS12 的更新,新系统的一些适配工作也在不停地进行,如果大家遇到问题,请及时向我们反馈。
开源与分享
- uniapp自定义底部导航,带凸起 @七月_
- swiper + scroll-view 实现下拉刷新 @杨大宝
- uni-app全局变量的几种实现方式:内置 vuex 的简单使用,示例中也有演示。
- uni-app中类似mui中的chat、im(聊天窗口)实现 @xcecd@qq.com
- UNI-Chat [不支持打包小程序] 简单配置 实现即时通讯 @健健
- HBuilder X对vue的支持有多强?:极致的 Vue 开发体验,就在 HBuilderX。
- 环信IM SDK 移植分享 @诗小柒
更多分享,请前往 精华区 查看。
欢迎更多的同学参与进来,分享自己的经验心得。
结束
本期周报就到这里,感谢大家的阅读。新的一周,祝大家工作顺利。

个推官方升级后PHP-SDK不能推送的问题解决方法
最近,个推官方更新了SDK。可能服务端也进行了升级,8月以后使用旧的php-sdk出现不能推送的情况。
升级php-sdk,问题同样没有解决。打开php报错显示,提示 “Can't use method return value in write context”。升级php至5.6.x后解决。
小结:
1、php-sdk不更新,导致个推推送失败。
2、新版本的php-sdk不支持5.4.x版本的php环境。
最近,个推官方更新了SDK。可能服务端也进行了升级,8月以后使用旧的php-sdk出现不能推送的情况。
升级php-sdk,问题同样没有解决。打开php报错显示,提示 “Can't use method return value in write context”。升级php至5.6.x后解决。
小结:
1、php-sdk不更新,导致个推推送失败。
2、新版本的php-sdk不支持5.4.x版本的php环境。

分享 PHP后端 + APP前端工程 实例-H5资讯APP , 开源工程下载
5资讯APP应用,是以资讯类APP为例,它的功能包括:前端APP模块,和 后端PHP 结合。
当新手们无从下手时,不知道怎么开始,怎么连接服务器获得数据,从实例中参考,可以让你认知大大提升,不需为一个简单的功能头痛几天都搞不定,从中举一反三,从而提升开发效率。
本案例是用沉浸式,就是把状态栏这部分空间也占据。
主要展示了,页面预加载,打开页面,页面传值,多图片上传,下载图片, 注册,登录,微信登录,分享,微信 和 支付宝支付,推送消息 等等,
让新手更加容易理解,学习起来也更容易举一反三。
使用的前端 APP 开发工具:HBuilder , 打包方式:在线打包
扫一扫下载安卓 dome app 体验
APP 部分页面展示
目前PHP 后台暂时使用的是:phpmywind 作为后台管理,但它不是必须,不一定要使用它,也可以使用其他的后台管理
PHP 后端功能包括:
1、文章发布,课程发布,栏目设置
2、用户管理,消息推送,应用分享,APP版本管理
3、商品订单管理,支付方式管理,
PHP 后台管理页面
php 后台文件结构:
下载及源码下载详情的介绍,可以到这里查看:http://www.html5-app.com/show/70
5资讯APP应用,是以资讯类APP为例,它的功能包括:前端APP模块,和 后端PHP 结合。
当新手们无从下手时,不知道怎么开始,怎么连接服务器获得数据,从实例中参考,可以让你认知大大提升,不需为一个简单的功能头痛几天都搞不定,从中举一反三,从而提升开发效率。
本案例是用沉浸式,就是把状态栏这部分空间也占据。
主要展示了,页面预加载,打开页面,页面传值,多图片上传,下载图片, 注册,登录,微信登录,分享,微信 和 支付宝支付,推送消息 等等,
让新手更加容易理解,学习起来也更容易举一反三。
使用的前端 APP 开发工具:HBuilder , 打包方式:在线打包
扫一扫下载安卓 dome app 体验
APP 部分页面展示
目前PHP 后台暂时使用的是:phpmywind 作为后台管理,但它不是必须,不一定要使用它,也可以使用其他的后台管理
PHP 后端功能包括:
1、文章发布,课程发布,栏目设置
2、用户管理,消息推送,应用分享,APP版本管理
3、商品订单管理,支付方式管理,
PHP 后台管理页面
php 后台文件结构:
下载及源码下载详情的介绍,可以到这里查看:http://www.html5-app.com/show/70
收起阅读 »
uni-app 教程更新! 共28讲,累计时长9小时!全面讲解 uni-app (从基础到进阶 + 小实战)^_^
课程章节共28讲,累计时长9小时!全面讲解 uni-app ^_^
- 介绍、部署、目录结构 2. 样式与布局 3. 配置相关 4. 生命周期
- 模板语法及数据绑定 6. class 及 style 7. 事件及事件绑定 8. 基础组件
- 表单及表单组件 10. 导航及页面传参 11. 多媒体组件 12. 网络请求
- 照片选择及预览 14. 文件上传及下载 15. 数据缓存 16. 设备相关
- 导航设置 18. 下拉刷新 19. 上拉加载 20. 跨端兼容
- 交互反馈 22. 第三方登录详解 23. 分享接口 24. 使用 iconfont 字体库
- 打包及课程推荐 26. 在 uni-app 中使用 vue.js 27. 自定义组件封装及调用 28. 新闻列表及详情实战
课程章节共28讲,累计时长9小时!全面讲解 uni-app ^_^
- 介绍、部署、目录结构 2. 样式与布局 3. 配置相关 4. 生命周期
- 模板语法及数据绑定 6. class 及 style 7. 事件及事件绑定 8. 基础组件
- 表单及表单组件 10. 导航及页面传参 11. 多媒体组件 12. 网络请求
- 照片选择及预览 14. 文件上传及下载 15. 数据缓存 16. 设备相关
- 导航设置 18. 下拉刷新 19. 上拉加载 20. 跨端兼容
- 交互反馈 22. 第三方登录详解 23. 分享接口 24. 使用 iconfont 字体库
- 打包及课程推荐 26. 在 uni-app 中使用 vue.js 27. 自定义组件封装及调用 28. 新闻列表及详情实战
详情请访问 http://www.hcoder.net/index/uniapp
收起阅读 »
微信授权登录后跳回app无任何回调事件
微信授权登录可以调起微信,但是在微信上点击确认登陆后跳回app,但是之后无任何回调事件。
问题原因:
1 因为我在集成Facebook登录的时候,在 AppDelegate.m 代码中按照FB示例,加入了如下代码:
2 以上代码会覆盖 AppDelegate.m 文件中同名的函数,造成拦截了微信授权登录的回掉事件,而并没有传给5+的相应事件来处理。
解决方法:
1 将FB的函数和5+的同名函数合并为如下:
微信授权登录可以调起微信,但是在微信上点击确认登陆后跳回app,但是之后无任何回调事件。
问题原因:
1 因为我在集成Facebook登录的时候,在 AppDelegate.m 代码中按照FB示例,加入了如下代码:
2 以上代码会覆盖 AppDelegate.m 文件中同名的函数,造成拦截了微信授权登录的回掉事件,而并没有传给5+的相应事件来处理。
解决方法:
1 将FB的函数和5+的同名函数合并为如下:

微信授权登录无响应,不回跳APP
微信授权登录可以调起微信,但是在微信上点击确认登陆后无响应,不回跳APP。
解决方法:
1 参考文章做排除:http://ask.dcloud.net.cn/article/309
2 我遇到的问题是因为下图第3部的item没有修改为自己的appid。并且这个在IOS平台5+SDK技术白皮书.docx并没有提及。
3 修改了以上item的值之后,微信授权回掉成功。
微信授权登录可以调起微信,但是在微信上点击确认登陆后无响应,不回跳APP。
解决方法:
1 参考文章做排除:http://ask.dcloud.net.cn/article/309
2 我遇到的问题是因为下图第3部的item没有修改为自己的appid。并且这个在IOS平台5+SDK技术白皮书.docx并没有提及。
3 修改了以上item的值之后,微信授权回掉成功。
收起阅读 »