小程序中tabBar页点击本页事件安卓和ios不一致的解决方法

小程序onTabItemTap在安卓下和ios不一致的解决方法

小程序项目,根据客户需求,需要在首页的时候,用户再次点击首页按钮,页面回到顶部,但是在其他页面的时候,切换回首页,应该显示用户上次流览的地方。我的导航栏是用tabBar配置的;首先想到的是小程序的onTabltemTap事件(小程序的解释:当前是 tab 页时,点击 tab 时触发);代码如下所示:

1
2
3
4
5
6
7
8
9
/*
当在本页的时候点击本页按钮
*/
onTabItemTap: function (item) {

wx.pageScrollTo({
scrollTop: 0,
duration: 300
},

这样写在开发者工具中测试是没问题的,可以达到我们要的效果,然后是iPhone手机测试也是没有问题的。但是,在安卓手机下,从其他页面切换回首页的时候,页面也会回到顶部,这样显然是不合理的。

又搜了小程序的其他方法,目测就这个能实现。现在的问题就是安卓手机上的问题,于是就对安卓手机进行兼容就好了。下面是解决方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 data: {
system: "",
isIndex: 1 // 判断是否是在index页,1为在,0为不在
},
/*
页面关闭
*/
onHide: function () {
this.data.isIndex = 0;
},
/*
当在本页的时候点击本页按钮
*/
onTabItemTap: function (item) {
console.log(item);
console.log(this.data.system)
if (this.data.system.indexOf("ios") > -1){
wx.pageScrollTo({
scrollTop: 0,
duration: 300
})
} else {
if(this.data.isIndex == 1) {
wx.pageScrollTo({
scrollTop: 0,
duration: 300
})
}else {
this.data.isIndex = 1;
}
}
},

实现逻辑就是首先判断是否是安卓机,如果是安卓则进行下面的判断,用一个变量判断是否是在本页面点击的,如果是在本页点击,则执行页面回顶部;如果是在其他页面切换过来的,则不执行,但是让判断是否本页的变量变为一,表示是在本页了;当页面切换出去的时候,让变量变为0,表示不在本页了。

字体按需压缩到最小

字体压缩

一. 在一个项目中,一定要用到华康娃娃体做一个效果,但是这个字体下下来有2.55MB,这显然是不行的,于是上网找了一波干货,如下:

字体压缩的原理就是你要使用的字符单独拿出来,不用的就不包含,这样就可以使得字体文件更小

方法一: 字体按需压缩网站

先来看看这个网站的使用,有一个框,里面说只支持zip压缩格式。其实只要一个你的字体文件,再加上一个html文件,两个通过zip格式压缩,然后拖拽到框里面,然后网站会自动压缩。最后你只要下载下来就行了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<style>
@font-face {
font-family: "lala";
src: url("hkwwt.ttf");
}
.a {
font-family: "lala";
}
</style>

<body>
<div class="a">0123456789.</div>
</body>

</html>

注意上面的div标签,里面放上你会用到的文字,然后保存 ——>压缩——>拖拽到网站;就行了,因为我只用到数字,所以就只写数字加标点

方法二: 用字蛛

1)首先在电脑上全局安装 font-spider

​ npm install font-spider -g (前提是是安装了nodejs)

2)新建一个文件夹,把名为华康娃娃体W5的字体文件放里面,

3)新建一个html,我的叫index.html:在里面输入:div里面放的就是你要使用的文字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<style>
@font-face {
font-family: "lala";
src: url("华康娃娃体W5.ttf");
}
.a {
font-family: "lala";
}
</style>

<body>
<div class="a">0123456789.</div>
</body>

</html>

4)最后在本文件夹下打开命令行,输入指令:

1
font-spider index.html

在本文件夹下面,原来的字体文件就被压缩了,还会新出现一个文件夹.font-spider里面存放的就是你原来的字体文件

从零开始用webpack搭建一个开发环境

Webpack从零开始配置一个开放环境

首先准备: 安装好nodejs( 意味着可以使用npm )

开始配置之旅

  1. 全局安装 webpack_cli 以确保可以使用webpack指令(在项目中也要安装)

    npm install webpack_cli -g (在项目中安装:npm install webpack_cli –save-dev)

  2. 新建一个文件夹,命名为use (路径最好不要有中文,会出什么bug我也不知道)

  3. 在use文件夹下打开命令行(在文件夹下按住shift键然后右击,选择在命令行打开)

    在命令行输入下面命令:npm init ; 然后一直默认就行了。

    完成以后会看到文件夹下多了一个package.json文件(这个文件可以存放我们安装的模块)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    {
    "name": "y",
    "version": "1.0.0",
    "description": "",
    "main": "webpack.config.js",
    "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack-dev-server"
    },
    "author": "",
    "license": "ISC",
    "devDependencies": {
    "babel-loader": "^7.1.4",
    "css-loader": "^0.28.10",
    "extract-text-webpack-plugin": "^4.0.0-beta.0",
    "html-webpack-plugin": "^3.0.6",
    "less": "^3.0.1",
    "less-loader": "^4.1.0",
    "style-loader": "^0.20.3",
    "vue": "^2.5.13",
    "webpack-dev-server": "^3.1.1"
    },
    "dependencies": {
    "webpack": "^4.1.1",
    "webpack-cli": "^2.0.11"
    }
    }

  4. 开始下载模块,我们先来下载webpack,和webpack_cli 模块

    npm install webpack webpack_cli –save-dev

    ( –save 是下载到当前的目录,而后面的-dev是将模块同步到package.json文件里面 )

    命令完成以后可以看到use文件夹下多了一个node_modules的文件夹,里面就是存放我们要使用的模块

  5. 在use文件夹下新建一个文件webpack.config.js,这个文件就是webpack的配置文件。

  6. 现在我们先来写下我们的开发目录吧

    ​ use—–> //项目目录

    ​ ->dist //文件打包后的目录

    ​ ->node_modules //存放要使用的插件的目录

    ​ src ——-> //我们的开发目录

    ​ ->css //存放css

    ​ ->img //存放图片的目录

    ​ ->js //存放js的目录

    ​ ->views //存放html的目录

    ​ —index.html //入口html

    ​ —index.js //入口js

    ​ —package.json

    ​ —webpack.config.js //webpack的配置文件

  7. 开始配置webpack.config.js

    (主要是src下的入口文件index.js通过webpack打包到dist文件夹下)

    // 引入模块
    var path = require(‘path’);
    const webpack = require(“webpack”);

    module.exports = {

1
2
3
4
5
6
7
8
9
10
11
// 页面入口文件,(html页面引入的唯一js文件)
entry: "./src/index.js",
// 对应输出项的配置
output: {
// 入口文件要输出的最终位置 (要放绝对路径)
path: path.normalize(__dirname+"/dist"),
// 输出文件的名称
filename: "index.js",
// 公共资源路径
publicPath: ""
},

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
index.html:

```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div class="a">webpack配置</div>
<script src="../dist/index.js"></script>
</body>
</html>

index.js

1
console.log("成功");

  1. package.json的配置中script里面按上面的展示的写

    直接在命令行输入: npm run dev

    运行完成以后,你会发现dist文件夹下多了一个index.html文件

  2. 上面的简单配置已经没有问题了,下面我们就来配置更多的模块。

    1. babel-loader : 这个包允许使用bable和webpack进行转换的js文件

      安装babel-loader 到项目: npm install babel-loader –save-dev

      在js文件夹下新建conmon.js文件:

      1
      2
      3
      4
      5
      6
      function showName(name) {
      console.log(name);
      }
      module.exports = {
      showName : showName
      }

      然后在index.js里面引入这个文件

      1
      2
      3
      4
      // 引入js文件
      const conmon = require("./js/conmon.js");

      conmon.showName("完成了关联");

      webpack.config.js配置:

      1
      2


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//  引入模块
var path = require('path');
const webpack = require("webpack");

module.exports = {
// 页面入口文件,(html页面引入的唯一js文件)
entry: "./src/index.js",
// 对应输出项的配置
output: {
// 入口文件要输出的最终位置 (要放绝对路径)
path: path.normalize(__dirname+"/dist"),
// 输出文件的名称
filename: "index.js",
// 公共资源路径
publicPath: ""
},
module: {
rules: [
{
test: /.js$/, // 要查找的以.js结尾的文件
exclude: /(node_modules|bower_components)/, //排除不需要查找的文件夹
use:['babel-loader'] // 使用的模块
},
]
},
}

打包以后,你会发现,conmon.js和index.js合并到了dist下的index下。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

1. style-loader  :  通过注入一个<style>标签将css添加到DOM中。

一般是配合css-loader来使用的



2. css-loader  :  css-loader会像import/require()一样解释@import和url()并解析他们

下载到项目:

num  install  style-loader  css-loader  --save-dev

在css文件夹下新建css文件index.css:

```css
.a {
width: 200px;
height: 200px;
background-color: #00ffff;
color: #ffffff;
font-size: 36px;
text-align: center;
}

在index.js引入:
1
2
3
4
5
6
7
// 引入js文件
const conmon = require("./js/conmon.js");
// 引入css文件
require("./css/index.css");

console.log("1234");
conmon.showName("完成了关联");
1
 
1
2


webpack.config.js配置:

1
2


1
```

// 引入模块
var path = require(‘path’);
const webpack = require(“webpack”);

module.exports = {
// 页面入口文件,(html页面引入的唯一js文件)
entry: “./src/index.js”,
// 对应输出项的配置
output: {
// 入口文件要输出的最终位置 (要放绝对路径)
path: path.normalize(__dirname+”/dist”),
// 输出文件的名称
filename: “index.js”,
// 公共资源路径
publicPath: “”
},
module: {
rules: [
{
test: /.js$/, // 要查找的以.js结尾的文件
exclude: /(node_modules|bower_components)/, //排除不需要查找的文件夹
use:[‘babel-loader’] // 使用的模块
},
// 将引入的css样式写入到标签的style属性中
{
test: /.css$/,
use: [‘style-loader’,’css-loader’]
},

  ]
},
1
2


}

1
2
3
4

在index.html使用下样式,则会看到标签样式加上去了。


  1. extract-text-webpack-plugin 插件:4)在打包过程中,把一类文本单独抽离出来

    (在上面的打包css的时候,css是直接写入到标签的style属性里面,这明显是有点菜的做法,那么我们可以通过这个插件把require的css文件单独抽出来,外部引入)

    安装: npm install extract-text-webpack-plugin@next –save-dev

    这里 extract-text-webpack-plugin 必须安装最新版本。

    Webpack 4.0 必须对应是 extract-text-webpack-plugin 4.0.0

    1
    2


1
2
3
4
5
//  引入模块
var path = require('path');
const webpack = require("webpack");
const ExtractTextPlugin = require("extract-text-webpack-plugin"); // 用于提取出 莫一类文件,单独生成文件,比如说单独抽离css
const ExtractCSS = new ExtractTextPlugin("css/style_1.css");
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
module.exports = {
// 页面入口文件,(html页面引入的唯一js文件)
entry: "./src/index.js",
// 对应输出项的配置
output: {
// 入口文件要输出的最终位置 (要放绝对路径)
path: path.normalize(__dirname+"/dist"),
// 输出文件的名称
filename: "index.js",
// 公共资源路径
publicPath: ""
},
module: {
rules: [
{
test: /.js$/, // 要查找的以.js结尾的文件
exclude: /(node_modules|bower_components)/, //排除不需要查找的文件夹
use:['babel-loader'] // 使用的模块
},
// 将引入的css样式写入到标签的style属性中
// {
// test: /.css$/,
// use: ['style-loader','css-loader']
// },
// 用插件是的css单独抽离,外部引入
{
test: /.css$/,
use: ExtractCSS.extract({
fallback: "style-loader", // 加载程序; css被提取时,加载的插件
use: [ // 装入器; css提取出来以后,加载为css
{
loader: "css-loader",
options: {
minimize : true // 是否压缩
}
}
]
})
},
]
},
// 插件
plugins: [
ExtractCSS, // 输出css
],
}

这样会生成一个css文件;但是,生成的文件不会动态自己添加到html代码中去,如果想要动态添加到代码,则需要下面的这个插件;


1
2
3
4

1. html-webpack-plugin : 插件简化了HTML文件的创建,以服务于您的bundle

安装:   npm i html-webpack-plugin --save-dev

const HtmlPlugin = require(“html-webpack-plugin”); // 用于动态生成html,可以动态添加js和css的外部引入

1
2

```js

1
2
3
4
5
6
7
//  引入模块
var path = require('path');
const webpack = require("webpack");
const ExtractTextPlugin = require("extract-text-webpack-plugin"); // 用于提取出 莫一类文件,单独生成文件,比如说单独抽离css
const ExtractCSS = new ExtractTextPlugin("css/style_1.css");

const HtmlPlugin = require("html-webpack-plugin"); // 用于动态生成html,可以动态添加js和css的外部引入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
module.exports = {
// 页面入口文件,(html页面引入的唯一js文件)
entry: "./src/index.js",
// 对应输出项的配置
output: {
// 入口文件要输出的最终位置 (要放绝对路径)
path: path.normalize(__dirname+"/dist"),
// 输出文件的名称
filename: "index.js",
// 公共资源路径
publicPath: ""
},
module: {
rules: [
{
test: /.js$/, // 要查找的以.js结尾的文件
exclude: /(node_modules|bower_components)/, //排除不需要查找的文件夹
use:['babel-loader'] // 使用的模块
},
// 将引入的css样式写入到标签的style属性中
// {
// test: /.css$/,
// use: ['style-loader','css-loader']
// },
// 用插件是的css单独抽离,外部引入
{
test: /.css$/,
use: ExtractCSS.extract({
fallback: "style-loader", // 加载程序; css被提取时,加载的插件
use: [ // 装入器; css提取出来以后,加载为css
{
loader: "css-loader",
options: {
minimize : true // 是否压缩
}
}
]
})
},
]
},
// 插件
plugins: [
ExtractCSS, // 输出css
new HtmlPlugin({ // 输出html
template: "src/index.html" // 以src下的index.html为模板打包
})
]
}

上面的配置,不需要自己在html中引入css和js,他会自动在打包的时候,给html添加js和css并且编译到dist里面。


1
2
3
4
5
6
7
8

1. less-loader : less文件编译

npm install less-loader --save-dev



```js

1
2
3
4
5
6
7
8
//  引入模块
var path = require('path');
const webpack = require("webpack");
const ExtractTextPlugin = require("extract-text-webpack-plugin"); // 用于提取出 莫一类文件,单独生成文件,比如说单独抽离css
const ExtractCSS = new ExtractTextPlugin("css/style_1.css");
const ExtractLESS = new ExtractTextPlugin("css/style_2.css");

const HtmlPlugin = require("html-webpack-plugin"); // 用于动态生成html,可以动态添加js和css的外部引入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
module.exports = {
// 页面入口文件,(html页面引入的唯一js文件)
entry: "./src/index.js",
// 对应输出项的配置
output: {
// 入口文件要输出的最终位置 (要放绝对路径)
path: path.normalize(__dirname+"/dist"),
// 输出文件的名称
filename: "index.js",
// 公共资源路径
publicPath: ""
},
module: {
rules: [
{
test: /.js$/, // 要查找的以.js结尾的文件
exclude: /(node_modules|bower_components)/, //排除不需要查找的文件夹
use:['babel-loader'] // 使用的模块
},
// 将引入的css样式写入到标签的style属性中
// {
// test: /.css$/,
// use: ['style-loader','css-loader']
// },
// 用插件是的css单独抽离,外部引入
{
test: /.css$/,
use: ExtractCSS.extract({
fallback: "style-loader", // 加载程序; css被提取时,加载的插件
use: [ // 装入器; css提取出来以后,加载为css
{
loader: "css-loader",
options: {
minimize : true // 是否压缩
}
}
]
})
},
// 使用less文件编译成css
{
test: /.less$/,
use: ExtractLESS.extract({
fallback: "style-loader",
use: [
{loader: "css-loader",options:{minimize: true}},
{loader:"less-loader"}
]
})
}
]
},
// 插件
plugins: [
ExtractCSS, // 输出css
ExtractLESS, // 输出less转化为css
new HtmlPlugin({ // 输出html
template: "src/index.html" // 以src下的index.html为模板打包
})
],
}

配置好后,只要在index.js里面引入less文件即可

1
2
3
4
5
6
7
8
9
// 引入js文件
const conmon = require("./js/conmon.js");
// 引入css文件
require("./css/index.css");
// 引入less文件
require("./css/style.less");

console.log("1234");
conmon.showName("完成了关联");

然后运行打包,就会发现less文件就被编译成了style_2.css;


1
2
3
4
5
6
7
8
9
10

1. webpack-dev-server :使用带有动态重新加载的开发服务器的webpack。这应该只用于开发。

安装: npm i webpack-dev-server --save-dev

插件的介绍里面没有标明什么用法,所以去看了下webpack的文档,里面有个属性 devServer即是在安装 webpack-dev-server插件以后配置的。

配置如下:


// 引入模块
var path = require(‘path’);
const webpack = require(“webpack”);
const ExtractTextPlugin = require(“extract-text-webpack-plugin”); // 用于提取出 莫一类文件,单独生成文件,比如说单独抽离css
const ExtractCSS = new ExtractTextPlugin(“css/style_1.css”);
const ExtractLESS = new ExtractTextPlugin(“css/style_2.css”);

const HtmlPlugin = require(“html-webpack-plugin”); // 用于动态生成html,可以动态添加js和css的外部引入
module.exports = {
// 页面入口文件,(html页面引入的唯一js文件)
entry: “./src/index.js”,
// 对应输出项的配置
output: {
// 入口文件要输出的最终位置 (要放绝对路径)
path: path.normalize(dirname+”/dist”),
// 输出文件的名称
filename: “index.js”,
// 公共资源路径
publicPath: “”
},
module: {
rules: [
{
test: /.js$/, // 要查找的以.js结尾的文件
exclude: /(node_modules|bower_components)/, //排除不需要查找的文件夹
use:[‘babel-loader’] // 使用的模块
},
// 将引入的css样式写入到标签的style属性中
// {
// test: /.css$/,
// use: [‘style-loader’,’css-loader’]
// },
// 用插件是的css单独抽离,外部引入
{
test: /.css$/,
use: ExtractCSS.extract({
fallback: “style-loader”, // 加载程序; css被提取时,加载的插件
use: [ // 装入器; css提取出来以后,加载为css
{
loader: “css-loader”,
options: {
minimize : true // 是否压缩
}
}
]
})
},
// 使用less文件编译成css
{
test: /.less$/,
use: ExtractLESS.extract({
fallback: “style-loader”,
use: [
{loader: “css-loader”,options:{minimize: true}},
{loader:”less-loader”}
]
})
}
]
},
// 插件
plugins: [
ExtractCSS, // 输出css
ExtractLESS, // 输出less转化为css
new HtmlPlugin({ // 输出html
template: “src/index.html” // 以src下的index.html为模板打包
})
],
// 开启服务
devServer : {
contentBase: path.join(
dirname+”/dist”), // 告诉服务器从哪里提供内容
open: true, // 服务器是否自动打开浏览器
openPage: ‘index.html’, //打开浏览器是指定打开的文件
port: 8080, // 设置端口号
proxy: { // 设置代理服务器
“/api”: {
target: “http://localhost:3000“, // 当在页面中输入 /api的时候,相当于 http://localhost:3000
pathRewrite: { // 改写路径
“^/api”: “”
}
}
},
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

Package.json配置:

看script属性下的dev属性:webpack-dev-server

```json
{
"name": "y",
"version": "1.0.0",
"description": "",
"main": "webpack.config.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-loader": "^7.1.4",
"css-loader": "^0.28.10",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"html-webpack-plugin": "^3.0.6",
"less": "^3.0.1",
"less-loader": "^4.1.0",
"style-loader": "^0.20.3",
"vue": "^2.5.13",
"webpack-dev-server": "^3.1.1"
},
"dependencies": {
"webpack": "^4.1.1",
"webpack-cli": "^2.0.11"
}
}

​ 然后配置好后,运行: npm run dev

则会自动开启服务器,当我们每次修改代码保存以后,会自动打包文件,并在我们的浏览器实时更新。

这样我们就把一个简单的开发环境搭建好了

用canvas做一个制作导入图片生成海报图片的小工具

利用canvas做一个插入图片,导出海报图片的工具

有张背景的海报图,当用户上传图片,图片在背景图的空白部分展示,并且点击可以生成显示的效果图片,利用canvas是很容易实现的

canvas的toDataURL()方法可以把canvas转化为base64的图片

直接来看看代码吧:

1
2
3
4
5
6
<div class="box">
<canvas id="cvs"></canvas>
<div class="b">生成图片</div>
</div>
<div class="z">
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
.box {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}

.b {
position: absolute;
bottom: 20px;
left: 150px;
background-color: #00ffff;
color: #ffffff;
width: 100px;
height: 50px;
line-height: 50px;
text-align: center;
}

.zz {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 100;
background-color: rgba(0, 0, 0, .8);
padding: 20px;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<script>
/*
获取canvas节点,并且设置canvas的宽高为屏幕宽高
*/
var canvas = document.getElementById("cvs");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
window.onresize = function (e) {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}

/*
设置在画布上的绘制环境
*/
var ctx = canvas.getContext("2d");
bgWrite();
writeImg("sc.png");

/*
海报背景图片的绘制
*/
function bgWrite(callback) {
var imgObj = new Image();
imgObj.src = "bg5.jpg";
imgObj.onload = function () {
ctx.drawImage(imgObj, 0, 0, window.innerWidth, window.innerHeight);
typeof callback == "function" && callback();
}
}

/*
传入要插入的图片地址,完成绘制
*/
function writeImg(src) {
bgWrite(function () {
var myImg = new Image();
myImg.src = src;
myImg.onload = function () {
/*
绘制后面插入的图片,宽高位置根据背景图位置决定
注意:安卓下是等比例,但是在ios下需要2倍
*/
if(navigator.userAgent.indexOf("iPhone")> -1) {
ctx.drawImage(myImg, 200, 400, 400, 400);
}
ctx.drawImage(myImg, 100, 200, 200, 200);
/*
img绘制完成,给点击事件,即点击导出图片到另一个div
*/
$(".b").on("click", function () {
console.log("sdfjktj")
var image = sheng(canvas);
$(".z").addClass("zz").append($("<img>").attr("src", image));
})
}

})
}

/*
传入要绘制图片的canvas节点,返回base64
*/
function sheng(node) {
var image = node.toDataURL("image/png");
return image;
}

</script>

简单的效果实现了,如果要实现点击上传图片,只要自己写一个上传图片的input标签,然后透明定位在放上传图片的位置,上传成功调用绘制的方法就行了

做一个新手指引的遮罩层效果,实现动态遮罩想要的标签

做一个新手指引,动态获取穿透位置

项目需要在微信公众号做一个新手指引的遮罩效果,于是搜素一波,发现一个css3属性:mask-image,于是对它研究了一番

mask-image:

​ 用一张图片,图片白色部分为遮罩,图片透明部分则是穿透。(反正我是这样用的,具体细节请查看文档)

1
2
3
4
5
6
7
8
9
10
11
.newguide_bg {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.70); /* 遮罩层的颜色 */
-webkit-mask-image: url(../../../images/common/newguide_bg.png); /* 图片识别穿透 */
-webkit-mask-size: 100% 100%;
z-index: 1002;
}

这样就有了遮罩的效果了。但是,遮罩的位置不同,还要做适配,那就来说说方法吧:

说说思路吧:首先一张mask图,然后根据要遮罩的宽高和位置,进行动态扩展和定位,这样就可以动态的进行自适应了

1、首先用ps做一张宽为320px,高为750px的图,里面在距离顶部200px,画一个高度为90px的矩形(由于我遮罩的地方宽度都是100%,所以这里宽度就100%);

2、其次就简单了,只要让图片根据你要的高度进行拉升,和调整位置就好了。下面是封装的函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
function setCssObj(size) {
size.height = size.height + 20; // 要遮罩标签的高度(高度加20 为了遮罩位置大一点点)
size.top = size.top - 10; // 要遮罩标签距离顶部的距离
var clientH = document.body.clientHeight; // 获取屏幕的高度
var imgH = 603; // 图片的高度
var imgBlankH = 30; // 图片透明部分的高度
var imgBlankTop = 90; // 图片透明部分离顶部的距离
var height = size.height;
var top = parseInt(size.top);

// 计算高度要扩大的比例和图片扩大以后要距离顶部的距离
var changeSize = ((imgH/clientH)*(height/imgBlankH))*100;
var changeTop = imgBlankTop * (height/imgBlankH);
// 返回一个对象,设置mask图片的位置和大小
return {
"-webkit-mask-size": "100% " + changeSize + "%",
"-webkit-mask-position-y":(changeTop - top)*-1
}
}

// 使用
$("#newguide").html(""); // 在html任意位置设置好的一个div标签,用于存放遮罩层html
var size = $("#boxCode").parent().offset(); // 回去要遮罩标签的信息
var cssObj = setCssObj(size); // 信息转化为cssObj
// 创建遮罩层
var newguideBoxcode = $("<div>").addClass("newguide_bg newguide_boxcode");
newguideBoxcode.css(cssObj); // 给遮罩层设置我们做好的样式
newguideBoxcode.appendTo($("#newguide")); // 见遮罩层添加到页面

这样我们就写完了!!

不等宽的和不等高的同理,这里就不多说了

小程序用web-view到入外部h5

项目需求,要在小程序里面引入一个外部的h5播放页面

web-view

组件是一个可以用来承载网页的容器,会自动铺满整个小程序页面

1
<web-view src="https://mp.weixin.qq.com/"></web-view>

话不多说,说说要达到的效果,首先我们在另外的一个页面点击播放以后,传入一个id进入web-view的页面里面,然后web-view页面通过不同的id来打开不同的外部网站

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* 页面的初始数据
*/
data: {
webSrc: "https://xxxxxx/index1.html?xxx=1",
},

/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
if (options.id > 0){
WebUrl = this.data.webSrc + "&xxxx=" + options.id;
}
this.setData({
webSrc: WebUrl
})
},
1
<web-view src='{{webSrc}}' ></web-view>

感觉这样没用什么问题,可是效果就是出不来。

反复找了好久,没找的问题,然而下面这样写就出来了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* 页面的初始数据
*/
data: {
webSrc: "",
},

/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
var WebUrl = "https://book.gzdaze.com/index1.html?isFull=1";
if (options.id > 0){
WebUrl = WebUrl + "&bookId=" + options.id;
}
this.setData({
webSrc: WebUrl
})
},

对没错,这样写就可以动态跳转到相应的页面。

具体的原因我也不知道,这得问开发者了。我猜测是首先加载的时候,webSrc写入到页面,然后web-view发现有HTTPS,然后就自动加载外部h5了,后面再改变网址就不生效了,毕竟他已经加载了外部页面。而下面的这种写法则是加载data的时候,传入到页面的是空值,web-view没用检测到合法地址,则不加载页面,到加载onLoad的时候,动态改变webUrl加载到页面,然后web-view发现有合法地址,然后加载外部h5

微信小程序写一个输入八位编号的输入框

首先看看我们要实现的效果

一、

效果和很多密码框一样,一个个输入。初看到这个效果感觉很简单,外层一个view,里面来8给text设置右边框为虚线,页面上就实现了效果。然后用一个input标签,定位在这个view上面。只要设置下input里面的字符间距。这里面有一个移动端也会遇到的设置字符间距问题,即是如果设置字符间距以后,input标签在输入前七个是没有问题的,当输入第八个数字的时候,因为要给光标留位置,所以整体会往前缩进,导致布局乱掉。

在小程序中抛开这个问题,小程序的input居然设置不了字符间距

二、

第一种方法pass掉,我们想想第二种方法,对,就用8个input标签,为了吸取上面的教训,先来看看小程序的input组件能不能手动设置聚焦,主要思路就是一个input标签输入完成以后马上失去焦点,让下一个input获取焦点。等等,这样切换小程序键盘会不会跟着切换?算了,试一下看看。于是又动手做了一波。

神奇的预言,效果可以实现输入和删除,可是键盘总是一闪一闪的,这用户体验会摔手机的好吧

三、

好汉不吃眼前亏,重新写过,综合两次经验,那就这样写吧,一个view把8个text包裹,先形成八个空格,然后用一个input标签定位在view,宽高都设为100%,z-index= -1,让其在view标签下面,不要被我们看到,然后输入的数字这一一映射到八个空格子里面,光标就用一个setTimeout循环显示隐藏。这样目测没什么问题了。开始动手一顿。

哈哈哈,开发这工具里面没什么问题了,效果可以实现了,用手机测试下,我去,隐藏不了,z-index没用;好我改,font-size我设置为0,还是隐藏不了;ok,那我再改,opacity我设置为:0,现在有用了吧,去,还没用。这个时候一脸懵逼

那就只能使用终极奥义,input的宽高设置为:0;现在出不来了吧,然后给外层view一个点击事件,动态的给那个不知道哪里去了的input获取焦点,然后输入数据,完成!!

最后看看源码吧,样式就不给出来了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<view >
<image></image>
<text>请输入8位电桩编号</text>
<text bindtap='scanCode'>点击扫码</text>
</view>
<view class="code_box">
<input bindinput='numberChange' type='number' maxlength='8' focus='{{focusShow}}' bindblur='{{loseBlur}}' value='{{boxCode}}'></input>
<view catchtap='showKeyboard'>
<view data-id='0'><text>{{boxcodearr[0] == "undefind" ? "" : boxcodearr[0]}}</text><text class='cursor {{focusnum == 1 ? "cursor_show" : "cursor_hid"}} {{ !cousor ? "cursor_op" : ""}}'></text></view>
<view data-id='1'><text>{{boxcodearr[1] == "undefind" ? "" : boxcodearr[1]}}</text><text class='cursor {{focusnum == 2 ? "cursor_show" : "cursor_hid"}} {{ !cousor ? "cursor_op" : ""}}'></text></view>
<view data-id='2'><text>{{boxcodearr[2] == "undefind" ? "" : boxcodearr[2]}}</text><text class='cursor {{focusnum == 3 ? "cursor_show" : "cursor_hid"}} {{ !cousor ? "cursor_op" : ""}}'></text></view>
<view data-id='3'><text>{{boxcodearr[3] == "undefind" ? "" : boxcodearr[3]}}</text><text class='cursor {{focusnum == 4 ? "cursor_show" : "cursor_hid"}} {{ !cousor ? "cursor_op" : ""}}'></text></view>
<view data-id='4'><text>{{boxcodearr[4] == "undefind" ? "" : boxcodearr[4]}}</text><text class='cursor {{focusnum == 5 ? "cursor_show" : "cursor_hid"}} {{ !cousor ? "cursor_op" : ""}}'></text></view>
<view data-id='5'><text>{{boxcodearr[5] == "undefind" ? "" : boxcodearr[5]}}</text><text class='cursor {{focusnum == 6 ? "cursor_show" : "cursor_hid"}} {{ !cousor ? "cursor_op" : ""}}'></text></view>
<view data-id='6'><text>{{boxcodearr[6] == "undefind" ? "" : boxcodearr[6]}}</text><text class='cursor {{focusnum == 7 ? "cursor_show" : "cursor_hid"}} {{ !cousor ? "cursor_op" : ""}}'></text></view>
<view data-id='7'><text>{{boxcodearr[7] == "undefind" ? "" : boxcodearr[7]}}</text><text class='cursor {{focusnum == 8 ? "cursor_show" : "cursor_hid"}} {{ !cousor ? "cursor_op" : ""}}'></text></view>
</view>
</view>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
data: {
boxcodearr: [],
focusnum: 0,
focusShow: false,
cousor : true,
cursorMove: ""
},

// 输入电桩编号
numberChange: function (e) {
console.log(e)
var value = e.detail.value.replace(/[\D]/g, '');
var arr = value.split('');
this.setData({
boxcodearr: arr,
boxCode : value
})
this.judgeFocus();
if (this.data.boxCode.length == 8) {
this.getBoxDetail();
} else {
this.boxCodeVerify();
}
},

// 给input标签聚焦
showKeyboard : function (e) {
this.setData({
focusShow: true
})
console.log(e.target.dataset.id);
this.judgeFocus();
},

// input标签失去焦点
loseBlur : function (e) {
console.log(e)
this.setData({
focusnum: 0
})
},
// 输入框改变时设置焦点位置
judgeFocus: function () {
var arr = this.data.boxcodearr;
var num = arr.length;
if(num == 0) num = 1;
this.setData({
focusnum : num
})
},
// 光标闪动函数
flashd : function () {
var that = this;
move();
function move() {
that.setData({
cousor : !that.data.cousor
})
that.cursorMove = setTimeout(move,500);
}
}

上面写的输入框可以实现基本功能,但是,只能够从最后一个位置开始删除,每次光标都出现的第一个没有数字的框

顾客是上帝,客户说要实现点击了哪个框删,就可以单独更改那个框,好吧,那就改呗

最终方案的逻辑不变,只需要做一些简单的改动。

上面方案三的显示的数字和input的值是挂钩的,那么我们把它们分成两个不同的,互相不影响。用光标的位置来对应每个框相应的值改变。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// 输入电桩编号
numberChange: function (e) {
console.log(e);
var value = e.detail.value.replace(/[\D]/g, '');
var arr = this.data.boxcodearr;
var focusnum = this.data.focusnum;
var boxCode = this.data.boxCode;
if (value.length > boxCode.length) {
var num = value[value.length - 1];
console.log(num);
if (arr[focusnum - 1] == "") {
arr[focusnum - 1] = num;
this.judgeFocus(true);
} else {
this.judgeFocus(true,true);
}
} else {
if (arr[focusnum - 1] == "") {
this.judgeFocus(false);
} else {
arr[focusnum - 1] = "";
this.judgeFocus(false, true);
}
value == "" ? value = "520" : value;
}
console.log(value)
this.setData({
boxCode: value,
boxcodearr: arr
})
this.judgeGet(arr);
},
// 输入框改变时,判断光标的位置
judgeFocus: function (add, noChange) {
var focusnum = this.data.focusnum;
if (add) {
focusnum++;
focusnum >= 8 ? focusnum = 8 : focusnum;
} else {
if (!noChange) {
focusnum--;
focusnum <= 1 ? focusnum = 1 : focusnum;
}
}
console.log(focusnum);
this.setData({
focusnum: focusnum
})
},
// 当输入八位输入框都满了的时候,调用接口
judgeGet(arr) {
var use = true;
for (var i = 0; i < arr.length; i++) {
if (arr[i] == "") {
use = false
}
}
if (use) {
this.getBoxDetail();
} else {
this.boxCodeVerify();
}
}

nodeJs开启本地服务器,即事件buffer和Stream的使用

用nodeJs开启本地服务器

nodeJs安装什么的就没什么好说了

1.找个文件夹,新建一个文件server.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*创建服务器*/

//引入http模块
var http = require('http');

//创建服务器
http.createServer(function(request,response){
//发送http头部
response.writeHead(200,{'content-Type':'text/plain'});
//发送响应数据
response.write('hello world\n');
//通知服务器响应头和响应体已经被发送
response.end();
}).listen(8888);

console.log('server running at http://127.0.0.1:8888/')

2.在文件夹打开命令行(按住shift然后右击文件夹,选择在命令行打开即可)

1
node server.js

3.然后在浏览器中打开http://127.0.0.1:8888/即是完成了

事件

event.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*事件驱动程序*/

//引入模块
var events = require('events');
//创建一个eventEmitter对象
var eventEmitter = new events.EventEmitter();
//绑定事件即事件处理程序
eventEmitter.on('start',Start);
eventEmitter.on('pass',Pass);
eventEmitter.on('end',End);

//事件触发
eventEmitter.emit('start');
eventEmitter.emit('pass');
eventEmitter.emit('end');

//函数
function Start(){
console.log("开始事件");
}
function Pass(){
console.log('经过事件');
}
function End(){
console.log('结束事件');
}

还有一些常用方法:

once(event, listener)
为指定事件注册一个单次监听器,即 监听器最多只会触发一次,触发后立刻解除该监听器。

removeListener(event, listener)
移除指定事件的某个监听器,监听器必须是该事件已经注册过的监听器。

removeAllListeners([event])
移除所有事件的所有监听器, 如果指定事件,则移除指定事件的所有监听器。

事件:

newListener
event - 字符串,事件名称listener - 处理事件函数该事件在添加新监听器时被触发。

removeListener
event - 字符串,事件名称listener - 处理事件函数从指定监听器数组中删除一个监听器。需要注意的是,此操作将会改变处于被删监听器之后的那些监听器的索引。

buffer

buffer.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/* 缓存区操作 */

//引入buffer模块
/*
在v6.0之前创建Buffer对象直接使用new Buffer()构造函数来创建对象实例,
但是Buffer对内存的权限操作相比很大,可以直接捕获一些敏感信息,
所以在v6.0以后,官方文档里面建议使用 Buffer.from() 接口去创建Buffer对象。
*/
var buf = Buffer.from('runoob','ascii');

//读取缓冲区数据
/*
buf.toString(encoding,start,end)
encoding -> 表示以什么编码读取
start -> 表示开始读取的索引位置
end -> 表示结束读取的索引位置
*/
console.log(buf.toString('utf8'));
console.log(buf.toString('hex'));
console.log(buf.toString('base64'));

//创建buffer类
/*
Buffer.alloc(size,fill) size->长度 fill->填充
Buffer.allocUnsafe(size) 比alloc()快,但返回的可能包含旧数据
Buffer.from(text) text可以是数组字符串的,如果为数组,这表示0xtext[i],字符串和其他则字节表示
*/
const buf1 = Buffer.alloc(10) //表示10长度,用0填充满
const buf2 = Buffer.alloc(10,1) //表示10长度,用0X1填充满
const buf3 = Buffer.allocUnsafe(10) //表示初始化一个10长度的
const buf4 = Buffer.from([1,2,3]) //创建一个包含[0x1,0x2,0x3]的buffer
const buf5 = Buffer.from('text') //创建一个以utf8字节的包含text的buffer
const buf6 = Buffer.from('text','latin1') //创建一个以Latin1字节的包含text的buffer

//写入缓冲区
/*
Buffer.write(string,offset,length,encoding)
string -> 写入缓冲区的字符串
offset -> 写入缓冲区的索引值 默认 0
length -> 写入缓冲区的长度 默认 buffer.length
encoding -> 写入缓冲区的编码 默认 ‘utf8’
*/
const buf7 = Buffer.alloc(11);
len = buf7.write('一生所爱');
console.log(len);

console.log('读取前面创建的数据')
console.log(buf1.toString('hex'))
console.log(buf2.toString('hex'))
console.log(buf3.toString('hex'))
console.log(buf4.toString('hex'))
console.log(buf5.toString('hex'))
console.log(buf6.toString())
console.log(buf7.toString())

//将buf转换为json对象
var json = buf6.toJSON();
console.log(json)

//缓冲区合并
const buf8 = Buffer.concat([buf1,buf2],20);
console.log(buf8.toString('hex'));

//缓冲区比较
/*
buf.compare(otherbuf) otherbuf -> 表示要比较的buffer
返回值 <0 -> buf在otherbuf之前
0 -> buf与otherbuf相同
>0 -> buf在otherbuf之后
*/
console.log(buf3.compare(buf4));

//缓存区拷贝
/*
buf.copy(targetBuf,start,end,length)
targeBuf -> 要拷贝的buffer
start -> 拷贝开始位置
end -> 拷贝结束位置
length -> 长度
*/


//缓存区裁剪
/*
buf.slice(start,end) 返回一个新的缓冲区,与原来的指向同一块位置
start -> 开始裁剪位置
end -> 结束裁剪位置
*/

//缓冲区长度
/*
buffer.length
*/

Node.js 目前支持的字符编码包括:

  • ascii - 仅支持 7 位 ASCII 数据。如果设置去掉高位的话,这种编码是非常快的。
  • utf8 - 多字节编码的 Unicode 字符。许多网页和其他文档格式都使用 UTF-8 。
  • utf16le - 2 或 4 个字节,小字节序编码的 Unicode 字符。支持代理对(U+10000 至 U+10FFFF)。
  • ucs2 - utf16le 的别名。
  • base64 - Base64 编码。
  • latin1 - 一种把 Buffer 编码成一字节编码的字符串的方式。
  • binary - latin1 的别名。
  • hex - 将每个字节编码为两个十六进制字符。

Stream(流)

stream.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

/* 流 */
/*
nodejs的stream有四种流类型
Readable - 可读操作
Writable - 可写操作
Duplex - 可读可写操作
Transfrom - 操作被写入,然后读出结果
Stream对象常用的事件:
data - 当有数据可读时触发
end - 没有更多的数据可读是触发
error - 在接收和写入过程中发生错误是触发
finish - 所有数据已经被写入到底层系统时触发
*/

//引入fs模块
var fs = require('fs');
//引入压缩模块
var zlib = require('zlib');
var data = '';

/* 创建可读流 */
var readerStream = fs.createReadStream('text.txt');
//设置编码
readerStream.setEncoding('utf8');
//处理流事件
readerStream.on('data',function(chunk){
data = chunk;
})
readerStream.on('end',function(){
console.log('读取结束');
console.log(data);
})
readerStream.on('error',function(err){
console.log(err);
})
console.log('程序结束');

/* 创建写入流 */
var writeStream = fs.createWriteStream('text.txt');
//写入数据
writeStream.write('我有一只小毛驴可我重来也不骑','utf8');
//标记文件末尾
writeStream.end();
//处理事件流
writeStream.on('finish',function(){
console.log('写入成功');
})
writeStream.on('error',function(err){
console.log(err);
})
console.log('写入流完毕')

/* 管道流 */
/*
管道流就是创建一个可读流,创建一个可写流,然后把读取到的数据通过可写流写到文件,即是管道流
*/

/* 链式流 */
/* 链式流一般用于管道操作 */
fs.createReadStream('input.txt')
.pipe(zlib.createGzip())
.pipe(fs.createWriteStream('input.txt.gz'))
console.log('文件压缩完成');

pipe:管

可以把数据流看成是一根管子,pipe即使在管中进行操作,对传输的数据进行操作

记用pychon写一个爬图片的网页爬虫

还不多说,直接上源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 引入两个模块
from urllib.request import urlopen
import re
import os
import shutil

def getHtml(url): #获取网页内容函数
page = urlopen(url)
html = page.read()
return html
def getImg(html): #传入网页的数据,筛选出我要的数据
reg = 'src="(.+?\.jpg)' #正则表达式
image = re.compile(reg);
imglist = re.findall(image, html)
return(imglist)
def writeFile(text): #把数据写入到文件中函数
print(os.getcwd()) #返回当前脚本的位置
print(os.listdir(os.getcwd())) #返回指定目录下的所有文件
fp = open("text.json",'w')
text1 ='{"data":["'+ '","'.join(text)+'"]}'
fp.write(text1)
fp.close()

html = getHtml('http://cz.mycar168.com/showspe/special_hailing/20180310hlgcz?baidujj-mingju&1=shenzhen-hailingchezhanpc&1=achezhanchezhan&1=%E8%BF%91%E6%9C%9F%E8%BD%A6%E5%B1%95&e_adposition=cl1&e_keywordid=53084209076#B_vid=9684476042573239518')
html = html.decode(); #将字节数据转换成string数据
writeFile(getImg(html))

text.json获取到的数据

1
{"data":["/images/award_1.jpg","/images/award_2.jpg","/images/award_3.jpg","http://img.mycar168.com/ueditor/upload/image/20180131/151738606434327750.jpg","http://img.mycar168.com/ueditor/upload/image/20180131/151738607359632797.jpg","http://img.mycar168.com/ueditor/upload/image/20180131/151738607969969444.jpg","/images/change/sz_gifts.jpg","/images/change/sz_hl.jpg","/images/change/qdyl.jpg","/images/change/zdcj.jpg","/images/change/gcyl.jpg","/images/change/hlq.jpg","/images/change/sz_gifts.jpg","http://img.mycar168.com/ueditor/upload/image/20170307/148885451958053172.jpg","http://img.mycar168.com/ueditor/upload/image/20170307/148885454658814605.jpg","http://img.mycar168.com/ueditor/upload/image/20170307/148885456187073170.jpg","http://img.mycar168.com/ueditor/upload/image/20170307/148885457885319765.jpg","/images/change/qrcode_chezhan.jpg"]}

踩的坑

1.urllib模块

1
在pychon3中,urllib是一个包,集成了用于处理url的模块。
1
2
3
4
一开始学pychon的时候看的是菜鸟教程里面的,而我用的是版本pychon3,里面的教程还是前面版本的,导致我直接引入urllib模块,使用urlopen方法的时候报错
urllib在pychon2与pychon3的区别:
转载自:http://blog.csdn.net/whatday/article/details/54710403
见下表:
Python 2 name Python 3 name
urllib.urlretrieve() urllib.request.urlretrieve()
urllib.urlcleanup() urllib.request.urlcleanup()
urllib.quote() urllib.parse.quote()
urllib.quote_plus() urllib.parse.quote_plus()
urllib.unquote() urllib.parse.unquote()
urllib.unquote_plus() urllib.parse.unquote_plus()
urllib.urlencode() urllib.parse.urlencode()
urllib.pathname2url() urllib.request.pathname2url()
urllib.url2pathname() urllib.request.url2pathname()
urllib.getproxies() urllib.request.getproxies()
urllib.URLopener urllib.request.URLopener
urllib.FancyURLopener urllib.request.FancyURLopener
urllib.ContentTooShortError urllib.error.ContentTooShortError
urllib2.urlopen() urllib.request.urlopen()
urllib2.install_opener() urllib.request.install_opener()
urllib2.build_opener() urllib.request.build_opener()
urllib2.URLError urllib.error.URLError
urllib2.HTTPError urllib.error.HTTPError
urllib2.Request urllib.request.Request
urllib2.OpenerDirector urllib.request.OpenerDirector
urllib2.BaseHandler urllib.request.BaseHandler
urllib2.HTTPDefaultErrorHandler urllib.request.HTTPDefaultErrorHandler
urllib2.HTTPRedirectHandler urllib.request.HTTPRedirectHandler
urllib2.HTTPCookieProcessor urllib.request.HTTPCookieProcessor
urllib2.ProxyHandler urllib.request.ProxyHandler
urllib2.HTTPPasswordMgr urllib.request.HTTPPasswordMgr
urllib2.HTTPPasswordMgrWithDefaultRealm urllib.request.HTTPPasswordMgrWithDefaultRealm
urllib2.AbstractBasicAuthHandler urllib.request.AbstractBasicAuthHandler
urllib2.HTTPBasicAuthHandler urllib.request.HTTPBasicAuthHandler
urllib2.ProxyBasicAuthHandler urllib.request.ProxyBasicAuthHandler
urllib2.AbstractDigestAuthHandler urllib.request.AbstractDigestAuthHandler
urllib2.HTTPDigestAuthHandler urllib.request.HTTPDigestAuthHandler
urllib2.ProxyDigestAuthHandler urllib.request.ProxyDigestAuthHandler
urllib2.HTTPHandler urllib.request.HTTPHandler
urllib2.HTTPSHandler urllib.request.HTTPSHandler
urllib2.FileHandler urllib.request.FileHandler
urllib2.FTPHandler urllib.request.FTPHandler
urllib2.CacheFTPHandler urllib.request.CacheFTPHandler
urllib2.UnknownHandler urllib.request.UnknownHandler
1
2
3
4
5
6
7
8
# 引入urllib.request模块的urlopen(打开url的方法)
from urllib.request import urlopen

def getHtml(url):
page = urlopen(url)
html = page.read()
print(html)
return html

2.是用re模块

1
2
3
4
5
6
7
8
9
10
在Python3以后,字符串和bytes类型彻底分开了。字符串是以字符为单位进行处理的,bytes类型是以字节为单位处理的。Python3中,bytes通常用于网络数据传输、二进制图片和文件的保存等等。可以通过调用bytes()生成bytes实例

文件的read方法读取到的数据是bytes类型

而re模块的findall方法只能处理string数据

解决方法:
type(b) 为bytes类型
string = b.decode() 直接以默认的utf-8编码解码bytes成string
b = string.encode() 直接以默认的utf-8编码string为bytes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 引入两个模块
from urllib.request import urlopen
import re

def getHtml(url):
page = urlopen(url)
html = page.read()
print(html)
return html
def getImg(html):
reg = 'src=(.+?\.jpg)' \
' alt='
image = re.compile(reg);
print(image)
imglist = re.findall(image, html)
print(imglist)
html = getHtml('http://sc.chinaz.com/tupian/fengjingtupian.html')
html = html.decode(); #以默认的utf-8编码解码bytes成string
print(type(html));
getImg(html)

来一波本地项目上传到github

1.找到要上传的项目文件夹,并打开命令行

1
按住shift键,右击鼠标,在此处打开powershell,或者在此处打开命令行

2.git初始化文件夹

1
git init

3.将代码上传到缓存区

1
git add .    //将所有代码上传到缓存区

4.将代码推送到本地库

1
2
git commit -m "注释语"   //-m  表示子提交缓存区的
git commit -am "注释语" //-am 相当于 git add 和 git commit -m 的组合

5.在github上新建项目,创建好后把地址拷贝

6.将本地仓库关联到github上

1
git remote add origin https://github.com/wangzai999/aa.github.io

7.将代码进行合并(这步是为了防止下一步上传代码报错)

1
git pull --rebase origin master

8.上传代码到github(如果是第一次上传代码,会弹出输入账号密码的窗口)

1
git push -u origin master

已经上传好了,当修改文件时,只需要 : 上传缓存区->上传本地库->上传到GitHub