wj'blog


  • 首页

  • 分类

  • 归档

  • 标签

  • 关于

  • 搜索

ES6数组

发表于 2017-12-22 | 分类于 ES6

介绍

本次介绍数组的一些扩展方法,都是简单地总结下一些方法的使用,详细的请参考:数组的扩展

阅读全文 »

ES6常用知识点总结(一)

发表于 2017-12-19 | 分类于 ES6

介绍

ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。

ES6新增的东西很多,我们不可能马上就掌握所有知识点,所以在这把常用到的知识点总结下。

阅读全文 »

webpack初体验之模块化开发

发表于 2017-12-12 | 分类于 JavaScript

写在前面的话

上次写过一篇关于webpack入门的博客,当时只是说借助node来完成开发,并用webpack打包以让浏览器识别。其实其主要思想就是实现前端模块化开发。
众所周知,历史上,JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。这在开发大型的、复杂的项目时就变得很困难。这就需要一种模块加载机制,在ES6之前,就有一些模块加载方案,比如CommonJS和AMD,上篇文章就是用到CommonJS规范。但现在,ES6已经填补了Module这块空白。下面就简单说下利用webpack实现前端模块化开发。

实例

介绍

本文主要介绍webpack的入门,因为我自己也是刚上手webpack,还在学习阶段,所以会讲得很基础。对于没用过webpack的童鞋,看完能懂就是我的目的。你也可以参考我的上篇博客webpack入门。另外关于ES6模块化,我觉得你应该要提前会懂,我就不讲了,这里有更好的文档 ES6 Module

阅读全文 »

Vuex详解

发表于 2017-12-10 | 分类于 Vue

什么是Vuex?

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。

在Vue中,多组件的开发给我们带来了很多的方便,但同时当项目规模变大的时候,多个组件间的数据通信和状态管理就显得难以维护。而Vuex就此应运而生。将状态管理单独拎出来,应用统一的方式进行处理,在后期维护的过程中数据的修改和维护就变得简单而清晰了。这个状态管理模式包含以下三个部分:

  • state,驱动应用的数据源;
  • view,以声明方式将 state 映射到视图;
  • actions,响应在 view 上的用户输入导致的状态变化。

简单说,就是用户界面触发动作(Action)进而改变对应状态(State),从而反映到视图(View)上,所以Vuex采用的是单向数据流的方式来管理数据的。官网给出以下图,很好做出示意:

阅读全文 »

对数组中的对象排序

发表于 2017-12-04 | 分类于 JavaScript

需求:
设计一个列表,包含:地域、百分比、人数、时间。请实现按照 人数 与 时间 的排序算法。

数据结构

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 data = [
{
area: '深圳',
percentage: 15,
number: 80,
staytime: 2
},
{
area: '北京',
percentage: 30,
number: 150,
staytime: 4
},
{
area: '广州',
percentage: 25,
number: 60,
staytime: 3
},
{
area: '上海',
percentage: 30,
number: 100,
staytime: 4
}
];

封装排序函数

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
/*
* 根据指定的字段和规则排序数据
* data Array 要排序的数据
* field string 排序依据的字段
* rule string 排序规则 DESC(降序) / ASC(增序)
* throw
* data is invalid : 要排序的数据不存在或类型不正确
* field is invalid : 排序参考字段不存在
* return Array 排序后的数据
*/


var mySort = function (data, field, rule){
if ( !(data instanceof Array) ) {
alert('数据不存在')
}
if ( !(field in data[0]) ) {
alert('排序参考字段不存在');
}
if ( !rule || ['DESC','ASC'].indexOf( (rule=rule.toString().toUpperCase()) ) == -1 ) {
rule = 'DESC'; //默认为降序
}

data.sort(function (a, b){
var v = a[field] - b[field];
return rule == 'ASC'? v:-v;
})
}

使用

1
2
3
mySort(data,'number','ASC'); // 若第三个参数不写,则默认为DESC

console.log(data);

js脚本测试动画

发表于 2017-11-30 | 分类于 JavaScript

前言

在使用css来给页面添加动画时,如果样式和动画一起写,很容易出错,最后可能在整体上达不到预期的效果,修修改改很费时,可以先写一个js脚本来测试动画效果,再去一次性写好所有动画。

测试过程

这里举一个小例子,来看看怎么先测试动画效果。

HTML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div class="screen1" style="background-color: #FFFF00;">
<h2 style="color: red;">这是第一屏</h2>

<p class="screen1_p1">第一段文字</p>
<p class="screen1_p2">第二段文字</p>
<p class="screen1_p3">第三段文字</p>
</div>

<hr>

<div class="screen2" style="background-color: #BDB76B;">
<h2 style="color: red;">这是第二屏</h2>

<p class="screen2_p1">第一段文字</p>
<p class="screen2_p2">第二段文字</p>
<p class="screen2_p3">第三段文字</p>
</div>

两个div代表两个屏,分别有不同的动画

阅读全文 »

vue自定义指令

发表于 2017-11-22 | 分类于 Vue

什么是指令?

指令 (Directives) 是带有 v- 前缀的特殊属性。
它可以写在DOM元素上,对html进行操作。常用的指令比如有:v-if,v-else,v-show,v-for等。这些都是官方直接给定的,另外Vue也允许注册自定义指令,有时这很有用。

自定义指令方法

自定义一个指令很简单,官网给出一个简单的例子,自定义一个聚焦指令v-focus

1
2
3
4
5
6
7
8
// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el) {
// 聚焦元素
el.focus()
}
})

上面几行代码就全局注册了一个指令并可以执行,当给一个输入框加上这个指令时,页面加载就会使该框获得焦点。

1
<input v-focus>

说明:

focus:如你所见,是指令的名称,不带v-前缀;

inserted:这是一个钩子函数,表示被绑定元素插入父节点时调用,指令定义函数提供了多个钩子函数,下面再介绍。

另外,你也可以局部注册指令,组件中也接受一个 directives 的选项:

1
2
3
4
5
6
7
8
directives: {
focus: {
// 指令的定义
inserted: function (el) {
el.focus()
}
}
}

钩子函数介绍

指令定义函数提供了几个钩子函数(可选)

  • bind:只调用一次,指令第一次绑定到元素时调用。

  • inserted:被绑定元素插入父节点时调用。

  • update:所在组件的VNode更新时调用,但是可能发生在其子 VNode 更新之前。

  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。

  • unbind:只调用一次,指令与元素解绑时调用。

他们中每一个都有相同的三个参数:el,binding和vnode,在update和componentUpdated中,还会有参数oldVnode,以区分传递的旧值和新值。

  • el:指令所绑定的元素,可以用来直接操作 DOM 。

  • binding:一个对象,包含以下属性:name,value,oldValue,expression,arg和modifiers。

  • vnode:Vue 编译生成的虚拟节点。

  • oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

注意:除了 el 之外,其它参数都应该是只读的。

其中,你注意到binding参数中有多个属性,要搞清楚他们分别代表了什么,这很重要。

1
2
3
<div id="app">
<p v-demo:foo.a.b="message"></p>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Vue.directive('demo',{
bind(el, binding, vnode){
//给绑定的元素添加内容
el.innerHTML = `
name:${binding.name};<br>
value:${binding.value};<br>
expression:${binding.expression};<br>
argument:${binding.arg};<br>
modifiers:${JSON.stringify(binding.modifiers)};
`
}
});


new Vue({
el:'#app',
data:{
message:"hello"
}
});

结果:

1
2
3
4
5
name:demo; //指令名,不包括 v- 前缀
value:hello; //指令的绑定值
expression:message; //字符串形式的指令表达式
argument:foo; //传给指令的参数,可选。
modifiers:{"a":true,"b":true}; //一个包含修饰符的对象。

还有一个oldValue是指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。

到这里,你可能有点糊涂了,东西看起来有点多,其实并不是,你只是不熟悉。这些官网介绍的很清楚,你需要的是一个更具体的例子。

写一个自己的指令

现在来创建一个自定义指令,比如我想创建一个可以操作定位的指令,就叫他 v-position。

1
2
3
4
5
6
Vue.directive('position',{
bind(el, binding, vnode){
el.style.position = 'fixed';
el.style.top = binding.value + 'px';
}
});

1
2
3
<div id="app">
<p v-position='100'>我距离顶部100px</p>
</div>

现在v-position只能控制到顶部的距离,我们还可以自由控制方向:

1
<p v-position:left='50'>我距离左侧50px</p>

1
2
3
4
5
6
7
Vue.directive('position',{
bind(el, binding, vnode){
el.style.position = 'fixed';
let d = (binding.arg == 'top'?'top':'left');
el.style[d] = binding.value + 'px';
}
});

另外,你还可以控制多个值:

1
<p v-position="{top:'100',left:'50'}">我距离左侧50px,距离顶部100px</p>

1
2
3
4
5
6
7
Vue.directive('position',{
bind(el, binding, vnode){
el.style.position = 'fixed';
el.style.top = binding.value.top + 'px';
el.style.left = binding.value.left + 'px';
}
});

这就是vue自定义指令的一些简单应用,你可以创建出更高级灵活的自定义指令。

webpack入门

发表于 2017-10-14 | 分类于 JavaScript

写在前面的话:

这不是一个很系统的教程,但是作为入门,我觉得够够了,至少知道怎么下手使用

为什么?(重要)

为什么要用webpack?答案网上一大堆。我不想说了,好吧,我也说不好,毕竟也才刚接触。

在这里,我觉得还是举个例子说明下吧,看完这个例子,你至少知道webpack还是有用的 (例子简单易懂哦~~)

首先新建一个目录,目录下建3个文件,分别是:

a.js:

1
2
3
(function() {
var msg = 'hello world'
})()

b.js:

1
console.log( msg )

index.html:

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>webpack study</title>
</head>
<body>

<script src="a.js"></script>
<script src="b.js"></script>
</body>
</html>

你看,代码多简单,肯定懂。其实就是在a中定义一个变量,然后要在b中打印出来,在html文件中先后引入a.js和b.js,这样看起来很合理,其实你又知道,这样根本打印不出来,甚至抛给你一个错误:

这是JavaScript语言性质决定的,我也不说了,很显然a.js和b.js没有关联,如果希望在b.js中访问到msg,办法是将msg定义到全局变量中,即修改a.js为:

1
2
3
(function() {
window.msg = 'hello world'
})()

这时候再去控制台,绝对打印出来了~~但是问题也很明显,这样定义到全局变量中的做法是不明智,为什么,我也不说了,你应该知道。

就在这时候,nodejs出现了,它解决了这个历史问题。可以用后台知识去写前端,这时分别修改a.js 和 b.js:

a.js:

1
2
3
var msg = 'hello world'

module.exports = {msg: msg}

b.js:

1
2
3
var msg = require('./a').msg

console.log( msg )

然后打开命令行工具进入当前目录,用node运行b.js:

结果正常打印了。

虽然问题解决了,不用定义全局变量了,但是更大的问题来了,就是这个是用node运行的,浏览器识别不了它,此时控制台是这样的:

啊哦,白忙活了,浏览器识别不了,玩个啥~ 其实,这才引出主题嘛,没错,到了这里,终于说到正题了,那就是为什么用webpack?

因为webpack就可以将这种好用的,但浏览器识别不了的东西编译成浏览器能够识别的东西,并使用。

使用webpack

安装:

1
2
3
4
5
//全局安装
npm install -g webpack

//安装到你的项目目录
npm install --save-dev webpack

可以选择全局安装,也可以安装在项目目录里,这里推荐安装到项目目录里:

首先新建一个文件夹,比如叫:webpack_study(即项目文件夹),然后进入文件夹,使用命令:

1
npm init -y

这个命令会自动生成一个package.json文件,这是一个标准的npm说明文件,里面蕴含了丰富的信息,包括当前项目的依赖模块,自定义的脚本任务等等。先不管它,这时在目录里安装webpack:

1
2
// 安装Webpack
npm install --save-dev webpack

安装完成后,目录里多了一个node_modules文件夹。现在将前面例子中的a.js,b.js和index.html等文件放入到目录中:

a.js:

1
2
3
var msg = 'hello world'

module.exports = {msg: msg}

b.js:

1
2
3
var msg = require('./a').msg

console.log( msg )

index.html:(注意:这里引用路径改变了,只引用了bundle.js)

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>webpack study</title>
</head>
<body>

<script src="bundle.js"></script>
</body>
</html>

现在整个目录结构如下:

正式使用webpack:

此时执行命令:

1
2
// 非全局安装的情况
node_modules/.bin/webpack b.js bundle.js

b.js是入口文件,bundle.js是我们要打包成的文件,即是我们在index.html中引用的文件。打包完成后,目录里多了一个bundle.js文件,这个时候再在浏览器里打开控制台,发现可以打印出“hello world了”,说明webpack已经帮我们处理好了依赖关系,浏览器可以正常工作了。当然,webpack的功能远比想像的强大。

现在学会了使用webpack打包文件,但是在终端输入了一堆命令,太复杂也容易出错,现在来看一种简单的打包方法。

通过配置文件来使用webpack:

在目录里新建一个js文件:webpack.config.js。这个是webpack的配置文件,内容为:

1
2
3
4
5
6
7
8
9
10
11
module.exports = {
  entry: __dirname + "/b.js", //唯一入口文件
  output: {
    path: __dirname, //打包后的文件存放的地方
    filename: "bundle.js" //打包后输出文件的文件名
  }


// 注:“__dirname”是node.js中的一个全局变量,它指向当前执行脚本所在的目录。

}

有了这个配置之后,再打包文件,只需在终端里运行(非全局安装需使用node_modules/.bin/webpack)命令就可以了,这条命令会自动引用webpack.config.js文件中的配置选项,示例如下:

现在打包就不用输入烦人的命令行参数了,是不是感觉很爽,但如果连 node_modules/.bin/webpack 都不用输入,是不是更爽,其实还真可以~

使打包更快捷:

方法就是在package.json文件中对scripts对象进行相关设置,设置方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"name": "webpack_study",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node_modules/.bin/webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^3.7.1"
}
}

现在再执行

1
npm run start

就可以打包了,如下:

是不是很方便。其实通过修改配置文件,还可以实现很多webpack的强大功能。都说webpack难,难就难在去配置文件吧。等我们需要用到某种功能时,再去学习怎么配置吧。

childNodes、children、firstChild和firstElementChild

发表于 2017-10-06 | 分类于 JavaScript

这是一段html代码:

1
2
3
4
5
6
7
8
9
10
<div id="div1">
hello world
<div>
<p>第一个p</p>
</div>

<div>
<p>第二个p</p>
</div>
</div>

  • childNodes:返回节点的子节点集合,以 NodeList 对象
1
console.log(div1.childNodes.length);  //5

因为childNodes会把文本算入节点,即使文本为空

  • children:返回节点的子节点,只返回元素节点
1
console.log(div1.children.length);  //2
  • firstChild:返回指定节点的首个子节点,以 Node 对象
1
2
3
4
console.log(div1.firstChild);  
//
// hello world
//

返回的是第一个文本节点

  • firstElementChild:返回指定节点的首个子节点,只返回元素节点
1
2
3
4
console.log(div1.firstElementChild);
// <div>
// <p>第一个p</p>
// </div>

二叉树节点查找与删除

发表于 2017-09-30 | 分类于 JavaScript

在上一篇关于二叉树的js实现的基础上,增加二叉树节点查找与删除操作。

代码如下:

注意:接口写在BinaryTree()中,部分代码已省略

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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
function BinaryTree(){
//...

//最小值查找
this.min = function(){
return minNode(root);
}

function minNode(node){
if (node) {
while(node && node.left !== null){
node = node.left;
}
return node.text;
}

return null;
}


//最大值查找
this.max = function(){
return maxNode(root);
}

function maxNode(node){
if (node) {
while(node && node.right !== null){
node = node.right;
}

return node.text;
}

return null;
}


//判断某值是否存在
this.search = function(text){
return searchNode(root,text);
}

function searchNode(node,text){
if (!node) {
return false;
}else if(text>node.text){
return searchNode(node.right,text);
}else if(text<node.text){
return searchNode(node.left,text)
}else{
return true;
}
}



//删除节点
this.remove = function(text){
root = removeNode(root,text);
}

function removeNode(node,text){
if (node === null) {
return null;
}

if (text<node.text) {
node.left = removeNode(node.left,text);
return node;
}else if (text>node.text) {
node.right = removeNode(node.right,text);
return node;
}else {
if (node.left === null && node.right === null) {
node = null;
return node;
}
if (node.left === null) {
node = node.right;
return node;
}else if (node.right === null) {
node = node.left;
return node;
}

var aux =findMinNode(node.right);
node.text = aux.text;
node.right = removeNode(node.right,aux.text);
return node;
}
}

function findMinNode(node){
if (node) {
while(node && node.left !== null){
node = node.left;
}

return node;
}
return null;
}

//...

}


//查找最小值
//console.log(binaryTree.min());

//查找最大值
//console.log(binaryTree.max());

//判断值是否存在
//console.log(binaryTree.search(7) ? '7 is found' : '7 is no found');
//console.log(binaryTree.search(9) ? '9 is found' : '9 is no found');


//删除节点
//binaryTree.remove(10);
1…3456
wungjyan

wungjyan

56 日志
9 分类
24 标签
RSS
练习册
© 2020 wungjyan
由 Hexo 强力驱动
|
主题 — NexT.Mist v5.1.2
本站访客数 人次 本站总访问量 次