牟骏荣博客


  • 首页

  • 安卓学习

  • Linux学习

  • 前端

  • 服务端

  • Python

Android 解决 NDK toolchains 加载失败

Posted on 2019-05-30 | In 安卓
  • Android 解决”No toolchains found in the NDK toolchains folder for ABI with prefix-mips64el-linux-android”错误
    今天安装了Android Studio 3.2,打开一个旧工程,编译提示”No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android”

网上也有解决办法,就是下载旧版的NDK,将其中的toolchain复制到新版的NDK中

但是感觉这种方式,不是解决的正道。

经过对新版NDK的研究,发现NDK的更新记录里有一段话

This version of the NDK is incompatible with the Android Gradle plugin
version 3.0 or older. If you see an error like
No toolchains found in the NDK toolchains folder for ABI with prefix: mips64el-linux-android,
update your project file to [use plugin version 3.1 or newer]. You will also
need to upgrade to Android Studio 3.1 or newer.

也就是说新版本的NDK与3.0及以前旧版的Android Gradle plugin插件不兼容
其实解决方法很简单,就是修改build.gradle中的红字部分,改为3.1以上版本即可

1
2
3
4
5
6
dependencies {
classpath 'com.android.tools.build:gradle:3.2.0'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}

实现input选择文件(图片)之后,预览图片的效果

Posted on 2019-05-17 | In 前端
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
// document.getElementById('file').onchange = function () {
// alert(this.value);
// this.value = null;
// };​

function upchange(){
console.log("----",document.getElementById("myfile").files[0]);

}

// $(function () {
// $('#myfile').change(function () {
// $(".img").attr("src", URL.createObjectURL($(this)[0].files[0]));
// getObjectUrl($(this)[0].files[0]);
// })
// })

function getObjectUrl(file) {
console.log("file", file);//文件
console.log("file", file.name);
console.log("file", file.size / 1024);
var url = null;
if (window.createObjectURL != undefined) {
url = window.createObjectURL(file);
} else if (window.URL != undefined) {
url = window.URL.createObjectURL(file);
} else if (window.webkitURL != undefined) {
url = window.webkitURL.createObjectURL(file);
}
console.log("url", url);
return url;

}

Sort operation used more than the maximum 33554432 bytes of RAM

Posted on 2019-05-06 | In linux , 服务端
  • 上线许久的产品突然爆出了一个Mongodb 查询的BUG,错误如下
    1
    2
    3
    4
    5
    6
    "exception":"org.springframework.data.mongodb.UncategorizedMongoDbException",
    "message":"Query failed with error code 96 and error message 'Executor error during find command: OperationFailed: Sort operation used more than the maximum 33554432 bytes of RAM. Add an index, or specify a smaller limit.' on server 127.0.0.1:27017;
    nested exception is com.mongodb.MongoQueryException:
    Query failed with error code 96 and error message 'Executor error during find command: OperationFailed: Sort operation used more than the maximum 33554432 bytes of RAM.
    Add an index, or specify a smaller limit.' on server 127.0.0.1:27017"
    Executor error during find command :: caused by :: Sort operation used more than the maximum 33554432 bytes of RAM. Add an index, or specify a smaller limit

原因比较明确:Sort operation used more than the maximum 33554432 bytes of RAM.,33554432 bytes算下来正好是32Mb,而Mongodb的sort操作是把数据拿到内存中再进行排序的,为了节约内存,默认给sort操作限制了最大内存为32Mb,当数据量越来越大直到超过32Mb的时候就自然抛出异常了!解决方案有两个思路,一个是既然内存不够用那就修改默认配置多分配点内存空间;一个是像错误提示里面说的那样创建索引。
首先说如何修改默认内存配置,在Mongodb命令行窗口中执行如下命令即可:

1
db.adminCommand({setParameter:1, internalQueryExecMaxBlockingSortBytes:335544320})

  • 我直接把内存扩大了10倍,变成了320Mb。从这里可以看出,除非你服务器的内存足够大,否则sort占用的内存会成为一个严重的资源消耗!然后是创建索引,也比较简单:

    1
    2
    db.yourCollection.createIndex({<field>:<1 or -1>})
    db.yourCollection.getIndexes() //查看当前collection的索引
  • 其中1表示升序排列,-1表示降序排列。索引创建之后即时生效,不需要重启数据库和服务器程序,也不需要对原来的数据库查询语句进行修改。创建索引的话也有不好的地方,会导致数据写入变慢,同时Mongodb数据本身占用的存储空间也会变多。不过从查询性能和服务器资源消耗这两方面来看,通过创建索引来解决这个问题还是最佳的方案!

django-查询语句

Posted on 2019-04-04 | In Python

1.model

  • 假设我们的model如下:
  • 某个JobType下有很多Job。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     class JobType(models.Model):
    name = models.CharField(max_length=10)
    description = models.CharField(max_length=100, null=True, blank=True)

    def __str__(self):
    return self.name

    class Job(models.Model):
    name = models.CharField(max_length=50)
    type = models.ForeignKey(JobType, related_name='jobs')
    city = models.CharField(max_length=30)
    experience = models.CharField(max_length=15)
    education = models.CharField(max_length=10)
    salary = models.CharField(max_length=15)
    public_time = models.DateTimeField()

    def __str__(self):
    return self.name

查询

  • 查询所有JobType

    1
    2
     JobType.objects.all()
    Out[1]: [<JobType: Java>, <JobType: Python>, <JobType: PHP>]
  • 对上述的queryset按名字排序(逆序则在字段前加减号‘-’,如order_by(‘-name’) )

    1
    2
    In [2]: JobType.objects.all().order_by('name')
    Out[2]: [<JobType: Java>, <JobType: PHP>, <JobType: Python>]
  • 查询name为‘Python’的JobType( 注意用get()方法得到的是单个对象而不是queryset,若有多个对象满足条件应该使用filter()方法。)

    1
    2
    In [3]: JobType.objects.get(name='Python')
    Out[3]: <JobType: Python>
  • 注意:1)若get()返回多个对象,会引发异常 MultipleObjectsReturned

  • 2)若没有对象符合查询条件,会引发异常 DoseNotExist,如:

    1
    JobType.objects.get(id=100)  # raises JobType.DoesNotExist
  • 查询所有JobType的name为Python的Job

    1
    2
    3
    4
    5
    In [4]: type = JobType.objects.get(name='Python')

    In [5]: Job.objects.filter(type=type)

    Out[5]: [<Job: Python开发工程师>, <Job: Python开发工程师>, <Job: python软件工程师>, <Job: Python>, <Job: Python开发>, <Job: Python>, <Job: Java/Python>, <Job: 大数据开发工程师JAVA、Scala、Python>, <Job: python开发工程师>, <Job: Python>, <Job: Python研发高级工程师>, <Job: Python开发>, <Job: Python工程师>, <Job: Python>, <Job: Python/PHP 语言开发工程师-YL>, <Job: Python工程师>, <Job: Python工程师(中高级)>, <Job: Python后台开发工程师>, <Job: python web开发实习生>, <Job: Python开发>, '...(remaining elements truncated)...']
  • 由于我们在Job model中定义type外键时,定义了related_name=‘jobs’,故还能用下面的方法查询

    1
    2
    3
    4
    5
    In [6]: type = JobType.objects.get(name='Python') 

    In [7]: type.jobs.all()

    Out[7]: [<Job: Python开发工程师>, <Job: Python开发工程师>, <Job: python软件工程师>, <Job: Python>, <Job: Python开发>, <Job: Python>, <Job: Java/Python>, <Job: 大数据开发工程师JAVA、Scala、Python>, <Job: python开发工程师>, <Job: Python>, <Job: Python研发高级工程师>, <Job: Python开发>, <Job: Python工程师>, <Job: Python>, <Job: Python/PHP 语言开发工程师-YL>, <Job: Python工程师>, <Job: Python工程师(中高级)>, <Job: Python后台开发工程师>, <Job: python web开发实习生>, <Job: Python开发>, '...(remaining elements truncated)...']
  • 当然,我们也可以用一条语句完成这个查询。就是下面的跨表查询,即外键 + 两条下划线 + 另一个表的字段:fk__field-in-foreign-model

    1
    2
    3
    In [8]: Job.objects.filter(type__name='Python')

    Out[8]: [<Job: Python开发工程师>, <Job: Python开发工程师>, <Job: python软件工程师>, <Job: Python>, <Job: Python开发>, <Job: Python>, <Job: Java/Python>, <Job: 大数据开发工程师JAVA、Scala、Python>, <Job: python开发工程师>, <Job: Python>, <Job: Python研发高级工程师>, <Job: Python开发>, <Job: Python工程师>, <Job: Python>, <Job: Python/PHP 语言开发工程师-YL>, <Job: Python工程师>, <Job: Python工程师(中高级)>, <Job: Python后台开发工程师>, <Job: python web开发实习生>, <Job: Python开发>, '...(remaining elements truncated)...']
  • 查询JobType的name为‘Python’之外的所有Job

    1
    2
    3
    In [9]: Job.objects.all().exclude(type__name='Python')

    Out[9]: [<Job: PHP/高级PHP工程师>, <Job: PHP开发工程师>, <Job: PHP>, <Job: PHP开发>, <Job: PHP>, <Job: PHP工程师>, <Job: PHP工程师>, <Job: PHP>, <Job: PHP研发工程师>, <Job: PHP开发工程师>, <Job: PHP>, <Job: PHP>, <Job: PHP开发工程师>, <Job: 高级PHP开发工程师>, <Job: PHP高级工程师>]
  • 转载

JS-HTML获取键盘事件

Posted on 2019-03-24 | In 前端

JS-HTML获取键盘事件

  • 直接上代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    document.onkeydown = function (event) {
    let e = event || window.event || arguments.callee.caller
    .arguments[0];
    if (e && e.keyCode == 13) {
    //that.login()
    执行代码
    }
    //可以用console.log(e.keyCode) 获取你想捕获的 key
    };
  • 希望可以帮到你

webStorm配置文件

Posted on 2019-03-20 | In javascript , 前端
1
2
3
4
5
6
7
8
9
10
11
-server
-Xms526m
-Xmx2048m
-XX:ReservedCodeCacheSize=1024m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=50
-ea
-Dsun.io.useCanonCaches=false
-Djava.net.preferIPv4Stack=true
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow
1
2
3
4
5
6
7
8
9
10
-Xms526m
-Xmx2048m
-XX:ReservedCodeCacheSize=1024m
-XX:+UseConcMarkSweepGC
-XX:SoftRefLRUPolicyMSPerMB=100
-ea
-Dsun.io.useCanonCaches=false
-Djava.net.preferIPv4Stack=true
-XX:+HeapDumpOnOutOfMemoryError
-XX:-OmitStackTraceInFastThrow

Python学习之爬虫案例

Posted on 2019-03-15 | In Python

Python学习之爬虫案例

– 直接上代码

python引入模块

1
2
import re
from urllib.request import urlopen

获取网页内容并返回

1
2
3
def getPage(url):
response = urlopen(url)
return response.read().decode('utf-8')

正则获取需要的内容

1
2
3
4
5
6
def parseHtml(s):
ret = re.findall(
'<li>.*?<span class="view">\s\W+(?P<vcount>\d+).*?<em>.*?</em>.*?</span>'
'.*?<div class="a1">.*?<a href="(?P<href>.*?)">(?P<title>.*?)</a>.*?</div>.*?</li>', s, re.S
)
return ret

内容保存

1
2
3
4
5
6
def writefile(dbs):
f = open(r'new.txt', "w+",encoding="utf-8")
for i in dbs:
print(i[0]+i[1]+i[2])
f.writelines(i[0]+i[1]+i[2] + '\n')
f.close()

启动调用方法

1
2
3
4
5
6
def main():
url = "http://www.yichang100.com/"
respones_html = getPage(url)
ret = parseHtml(respones_html)
writefile(ret)
main()

通俗浅显的理解Promise中的then

Posted on 2019-03-07 | In 前端
  • Promise,ES6中定义的规范,不会使用Promise,都不敢说自己用过ES6,大部分介绍Promise的规范的文章对于新手小白来说看得云里雾里,且并不是通俗易懂。本文通过实例介绍讲述Promise中then的的最通俗应用理解,代码建立在不出现异常的情况的操作下,不严谨之处,请以官方规范为标准。

    Pomise then的使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    let fun = function () {
    // 这里可以是一个异步请求
    return new Promise((resolve, reject) => {
    resolve('成功了')
    })
    };
    fun()
    .then(v => {
    console.log(v);
    console.log('func over');
    })
    .catch(e => {
    console.log(e);
    });
    //打印结果
    成功了
    func over

Pomise.all的使用

  • Promise.all可以将多个Promise实例包装成一个新的Promise实例。同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
let p1 = new Promise((resolve, reject) => {
resolve('成功了')
})

let p2 = new Promise((resolve, reject) => {
resolve('success')
})

let p3 = Promse.reject('失败')

Promise.all([p1, p2]).then((result) => {
console.log(result) //['成功了', 'success']
}).catch((error) => {
console.log(error)
})

Promise.all([p1,p3,p2]).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error) // 失败了,打出 '失败'
})
  • Promse.all在处理多个异步处理时非常有用,比如说一个页面上需要等两个或多个ajax的数据回来以后才正常显示,在此之前只显示loading图标。
    代码模拟:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    let wake = (time) => {
    return new Promise((resolve, reject) => {
    setTimeout(() => {
    resolve(`${time / 1000}秒后醒来`)
    }, time)
    })
    }

    let p1 = wake(3000)
    let p2 = wake(2000)

    Promise.all([p1, p2]).then((result) => {
    console.log(result) // [ '3秒后醒来', '2秒后醒来' ]
    }).catch((error) => {
    console.log(error)
    })
  • 需要特别注意的是,Promise.all获得的成功结果的数组里面的数据顺序和Promise.all接收到的数组顺序是一致的,即p1的结果在前,即便p1的结果获取的比p2要晚。这带来了一个绝大的好处:在前端开发请求数据的过程中,偶尔会遇到发送多个请求并根据请求顺序获取和使用数据的场景,使用Promise.all毫无疑问可以解决这个问题。

Promise.race的使用

  • 顾名思义,Promse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    let p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
    resolve('success')
    },1000)
    })

    let p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
    reject('failed')
    }, 500)
    })

    Promise.race([p1, p2]).then((result) => {
    console.log(result)
    }).catch((error) => {
    console.log(error) // 打开的是 'failed'
    })
  • 原理是挺简单的,但是在实际运用中还没有想到什么的使用场景会使用到。

Echart相关资源整理

Posted on 2019-03-06 | In 前端

Echart官网

Echart官方地址

全部地图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
28
29
30
31
32
33
34
35
https://mjronlines.github.io/assets/echartjson/anhui.json
https://mjronlines.github.io/assets/echartjson/aomen.json
https://mjronlines.github.io/assets/echartjson/beijing.json
https://mjronlines.github.io/assets/echartjson/china.json
https://mjronlines.github.io/assets/echartjson/chongqing.json
https://mjronlines.github.io/assets/echartjson/fujian.json
https://mjronlines.github.io/assets/echartjson/gansu.json
https://mjronlines.github.io/assets/echartjson/guangdong.json
https://mjronlines.github.io/assets/echartjson/guangxi.json
https://mjronlines.github.io/assets/echartjson/guizhou.json
https://mjronlines.github.io/assets/echartjson/hainan.json
https://mjronlines.github.io/assets/echartjson/hebei.json
https://mjronlines.github.io/assets/echartjson/heilongjiang.json
https://mjronlines.github.io/assets/echartjson/henan.json
https://mjronlines.github.io/assets/echartjson/hubei.json
https://mjronlines.github.io/assets/echartjson/hunan.json
https://mjronlines.github.io/assets/echartjson/jiangsu.json
https://mjronlines.github.io/assets/echartjson/jiangxi.json
https://mjronlines.github.io/assets/echartjson/jilin.json
https://mjronlines.github.io/assets/echartjson/liaoning.json
https://mjronlines.github.io/assets/echartjson/neimenggu.json
https://mjronlines.github.io/assets/echartjson/ningxia.json
https://mjronlines.github.io/assets/echartjson/qinghai.json
https://mjronlines.github.io/assets/echartjson/shandong.json
https://mjronlines.github.io/assets/echartjson/shanghai.json
https://mjronlines.github.io/assets/echartjson/shanxi.json
https://mjronlines.github.io/assets/echartjson/shanxi1.json
https://mjronlines.github.io/assets/echartjson/sichuan.json
https://mjronlines.github.io/assets/echartjson/tianjin.json
https://mjronlines.github.io/assets/echartjson/xianggang.json
https://mjronlines.github.io/assets/echartjson/xinjiang.json
https://mjronlines.github.io/assets/echartjson/xizang.json
https://mjronlines.github.io/assets/echartjson/yunnan.json
https://mjronlines.github.io/assets/echartjson/zhejiang.json
https://mjronlines.github.io/assets/echartjson/HK.json

VSCode - Beautify插件配置

Posted on 2019-02-28 | In 前端

1.使用Beautify插件配置 自动格式化按如下步骤设置

  • 在工作目录下建立.jsbeautifyrc文件.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    {
    "brace_style": "none,preserve-inline",
    "indent_size": 2,
    "indent_char": " ",
    "jslint_happy": true,
    "unformatted": [""],
    "css": {
    "indent_size": 2
    }
    }

注释

  • brace_style,格式风格,详见官方说明(为避免和eslint默认检查冲突,建议此属性设置为 none,preserve-inline)
  • indent_size,缩进长度(为避免和eslint默认检查冲突,建议此属性设置为 2)
  • indent_char,缩进填充的内容(充满♂)
  • jslint_happy:true,若你要搭配jslint使用,请开启此选项
  • unformatted:[“a”,”pre”],这里放不需要格式化的标签类型。注意 template 也是默认不格式化的,.vue 的template 标签如果需要格式化请在 .jsbeautifyrc 重新定义不带 template 的声明属性

2.启用保存时自动

在VSCode的配置文件里添加 editor.formatOnSave:true 即可实现保存时自动格式化

3.快捷键

在 VS Code 的键盘快捷方式文件里添加

1
2
3
4
5
{
"key": "cmd+b", // 自己定键位
"command": "HookyQR.beautify",
"when": "editorFocus"
}

4.单独配置vue

  • 文件-> 设置 -> settings.json 中添加属性
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    "beautify.language": {
    "js": {
    "type": [
    "javascript",
    "json"
    ],
    "filename": [
    ".jshintrc",
    ".jsbeautify"
    ]
    },
    "css": [
    "css",
    "scss"
    ],
    "html": [
    "htm",
    "html",
    "vue" //< 这条给vue配置
    ]
    }

插件备份(自己研究)

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
{
  // The plugin looks for a .jsbeautifyrc file in the same directory as the
  // source file you're prettifying (or any directory above if it doesn't exist,
  // or in your home folder if everything else fails) and uses those options
  // along the default ones.


  // Details: https://github.com/victorporof/Sublime-HTMLPrettify#using-your-own-jsbeautifyrc-options
  // Documentation: https://github.com/einars/js-beautify/
  "html": {
    "allowed_file_extensions": ["htm", "html", "xhtml", "shtml", "xml", "svg","aspx","jsp"],
    "brace_style": "collapse", // [collapse|expand|end-expand|none] Put braces on the same line as control statements (default), or put braces on own line (Allman / ANSI style), or just put end braces on own line, or attempt to keep them where they are
    "end_with_newline": false, // End output with newline
    "indent_char": "\t", // Indentation character
    "indent_handlebars": false, // e.g. {{#foo}}, {{/foo}}
    "indent_inner_html": false, // Indent <head> and <body> sections
    "indent_scripts": "keep", // [keep|separate|normal]
    "indent_size": 1, // Indentation size
    "max_preserve_newlines": 10, // Maximum number of line breaks to be preserved in one chunk (0 disables)
    "preserve_newlines": true, // Whether existing line breaks before elements should be preserved (only works before elements, not inside tags or for text)
    "unformatted": ["a", "span", "img", "code", "pre", "sub", "sup", "em", "strong", "b", "i", "u", "strike", "big", "small", "pre", "h1", "h2", "h3", "h4", "h5", "h6"], // List of tags that should not be reformatted
    "wrap_line_length": 0 // Lines should wrap at next opportunity after this number of characters (0 disables)
  },
  "css": {
    "allowed_file_extensions": ["css", "scss", "sass", "less"],
    "end_with_newline": false, // End output with newline
    "indent_char": "\t", // Indentation character
    "indent_size": 1, // Indentation size
    "newline_between_rules": true, // Add a new line after every css rule
    "selector_separator": " ",
    "selector_separator_newline": false // Separate selectors with newline or not (e.g. "a,\nbr" or "a, br")
  },
  "js": {
    "allowed_file_extensions": ["js", "json", "jshintrc", "jsbeautifyrc","csslintrc"],


    // Set brace_style
    //  collapse: (old default) Put braces on the same line as control statements
    //  collapse-preserve-inline: (new default) Same as collapse but better support for ES6 destructuring and other features. https://github.com/victorporof/Sublime-HTMLPrettify/issues/231
    //  expand: Put braces on own line (Allman / ANSI style)
    //  end-expand: Put end braces on own line
    //  none: Keep them where they are
    "brace_style": "collapse",//"collapse-preserve-inline"


    "break_chained_methods": false, // Break chained method calls across subsequent lines
    "e4x": false, // Pass E4X xml literals through untouched
    "end_with_newline": false, // End output with newline
    "indent_char": "\t", // Indentation character
    "indent_level": 0, // Initial indentation level
    "indent_size": 1, // Indentation size
    "indent_with_tabs": true, // Indent with tabs, overrides `indent_size` and `indent_char`
    "jslint_happy": true, // If true, then jslint-stricter mode is enforced
    "keep_array_indentation": false, // Preserve array indentation
    "keep_function_indentation": false, // Preserve function indentation
    "max_preserve_newlines": 0, // Maximum number of line breaks to be preserved in one chunk (0 disables)
    "preserve_newlines": true, // Whether existing line breaks should be preserved
    "space_after_anon_function": false, // Should the space before an anonymous function's parens be added, "function()" vs "function ()"
    "space_before_conditional": true, // Should the space before conditional statement be added, "if(true)" vs "if (true)"
    "space_in_empty_paren": false, // Add padding spaces within empty paren, "f()" vs "f( )"
    "space_in_paren": false, // Add padding spaces within paren, ie. f( a, b )
    "unescape_strings": false, // Should printable characters in strings encoded in \xNN notation be unescaped, "example" vs "\x65\x78\x61\x6d\x70\x6c\x65"
    "wrap_line_length": 0 // Lines should wrap at next opportunity after this number of characters (0 disables)
  }
}
12…6

牟骏荣

52 posts
11 categories
57 tags
loading css3 动态特效 android View angular drawable dom Scroll 鼠标拖动 express nodejs git 前端 ubuntu linux ionic relativelayout 相对布局 VSCode webview RecyclerView javascript nginx ueditor nodeJs shell chrome gitee VUE linearlayout 瀑布流 实例 php GPS 工具类 mongodb 百度地图 demo echart 图标 资源 Promise python 爬虫 webstorm js django sql 正则表达式 mongo intput 预览图片 验证码 close phone scroll
© 2019 牟骏荣