Giter Site home page Giter Site logo

jscode's People

Contributors

raclen avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar

jscode's Issues

正则表达式-零宽断言

先看一下零宽度正预测先行断言( 格式为 (?=exp) )
我们来看一下

var reg = /(?=a)b/;  
reg.exec("ab");//null

零宽断言 断言的是后面出现的东西,所以上一个正则表达式永远匹配不到东西
改一下

var reg = /(?=a)\wb/;  
reg.exec("cabd");//ab

当我看到这的时候我想这不是和/ab/一个意思了?其实不是的
这里的ab 是\wb
零宽断言一般是放后面匹配的,来看一下这个例子

var reg = /123(?=abc)/;  
reg.exec("aaa123abcsss"); 
["123"]

(?=abc)这个东西只参与匹配不捕获
下面我们来匹配一个字符串

设:有字符串 var s = 'aaalllsss9tAAAnnn999';
问:请找出所有在 "9" 前的相邻 3个连续相同字符

因为正则的exec一直匹配一个,这里我们用JavaScript中字符串的match方法

var s = 'aaalllsss9tAAAnnn999';
s.match(/(\w)\1{2}(?=9)/g)
["sss", "nnn"]

这样只能断言后面的,应该要有反向零宽断言才是
再来看一下(?!)用法

设:有字符串 var web_development = "python php ruby javascript jsonp";
问:请找出所有含有p但是不含有on的单词

web_development.match(/\b(?=\w*p)(?!\w*on)\w*\b/g)
["php", "javascript"]

(?<=exp)也挺好用的,JavaScript不支持
比如我们要匹配这段字符串[]中的数字
image
群里看到了一个题目

问个问题啊:【小题1】skdasdajs阿斯顿d 【小题2】asdasdagasfga【小题3】GSDS刷卡机啊手机打,怎么匹配【小题N】及后面的内容啊

这个问题的难点是匹配最后一个
下面是代码

'问个问题啊:【小题1】skdasdajs阿斯顿d 【小题2】asdasdagasfga【小题3】GSDS刷卡机啊手机打,怎么匹配【小题N】及后面的内容啊求'.match(/【小题\w+】.*?(?=【小题\w+)/g)
["【小题1】skdasdajs阿斯顿d ", "【小题2】asdasdagasfga", "【小题3】GSDS刷卡机啊手机打,怎么匹配"]
'问个问题啊:【小题1】skdasdajs阿斯顿d 【小题2】asdasdagasfga【小题3】GSDS刷卡机啊手机打,怎么匹配【小题N】及后面的内容啊求'.match(/【小题\w+(([\s\S]*?)(?=【小题\w+)|([\s\S]*?)$)/g)
["【小题1】skdasdajs阿斯顿d ", "【小题2】asdasdagasfga", "【小题3】GSDS刷卡机啊手机打,怎么匹配", "【小题N】及后面的内容啊求"]

下面这个例子具有代表性
校验密码必须包含字母、数字和特殊字符,6-16位

需求:校验密码必须包含字母、数字和特殊字符,6-16位,假定特殊字符为 -_= 三个字符
源串:
12345
123456
1234561234561234
12345612345612345
a1234
a12345
-1234
-12345
a-123
a-1234
a-1234a-1234a-12
a-1234a-1234a-1234
aaaaa
aaaaaa
-_=-_
-_=-_=
预期:匹配
a-1234
a-1234a-1234a-12
/^(?=.*?[a-zA-Z])(?=.*?[0-9])((?=.*?[-_=])).{6,16}$/gm

参考
正则表达式30分钟入门教程
掘金的一篇文章
正则表达式之:零宽断言不『消费』
教你怎么理解正则表达式之零宽断言(环视)
深入正则表达式应用
正则掌握程度测试题

#2016-06-07

webpack-神奇的前端工具

webpack只是工具不涉及浏览器兼容

最早接触webpack是15年初,那时候也写了几个dome,去年的文章
但是有模块化的没模块的组合,不知道怎么处理,但是RJS可以处理各种有模块化,没模块化的,就一直用的RJS。废话不多话,开始介绍webpack
webpack的基本使用很容易,只要你按照commonjs规范些,commonjs规范是啥的,我觉得其实就是写完一段代码,把要暴露的变量挂载到exports上
例如
//a.js

var a = "你好";
module.exports = a;

//b.js

var a = require('a.js');
console.log(a)//你好

对于commonjs规范的和没规范的js文件怎么打包
1、将没有模块化规范的文件和入口文件作为一个数组,没有模块化的放在前面
例如

//zepto是没有模块化的,main是我们的入口js
entry: {
        main: ["./src/js/zepto.js", './src/js/main.js'],
   },
   ... 

2、使用exports-loader插件
使用exports会在没有模块定位的文件后面把你写的变量挂载到 module.exports上,这样就成了commonjs规范
安装完exports-loader插件后,配置文件改成

    module: {
      //加载器配置
      loaders: [
          { test: require.resolve('./src/js/zepto.js'), loader: "exports?Zepto" }
      ]
  },

其它地方正常引入zepto
打包后,在文件中你会看到这么一句话

 /*** EXPORTS FROM exports-loader ***/
module.exports = Zepto;

因此使用exports-loader符合webpack的加载**.
如果想把公共的打个包可以用uglify
npm install uglify-js -g
"uglify": "uglifyjs src/common/jquery.js src/common/handlebars.js src/common/util.js -o js/common/common.js"
公共模块提取
当多个入口文件引入同一个文件的时候,使用CommonsChunkPlugin可以把它们提取出来(这点 很智能)

var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('dist/js/common.js');
module.exports = {
    entry: {
        // main: ["./src/js/zepto.js", './src/js/main.js'],
        main: "./src/js/main.js",
        app: "./src/js/app.js",
    },
    ...
plugins: [
        commonsPlugin
    ],

你也可以通过配置把它们拿出来

image

webpack 加载css也很容易
require('style.css')//和加载js一样
这样打包之后,css会通过style标签引入在页面上
其实这样也没啥影响,改还是该源文件,可能有的人看起来不爽,好吧,我们和其它打包工具一样,把它导出来
这里要用上extract-text-webpack-plugin插件

var ExtractTextPlugin = require('extract-text-webpack-plugin');
plugins: [
        new ExtractTextPlugin('dist/css/[name].min.css'),//把css作为单独文件导出
    ],

webpack设置banner

plugins: [
        new webpack.BannerPlugin('This file is created by '+ newDate().toLocaleString())//设置文件头
    ],

编译sass 我就不说了
下面来说说按需加载(这个很重要)
这里要用到bundle-loader插件

//第一个lazy表示延迟加载,第二个是模块的名字(不写打包出来的没名字)
var loadlazy = require("bundle?lazy&name=lazy!./lazy.js");
//点击的时候加载
jquery('.test').on('click',function(){
    loadlazy(function(m) {
        console.log(m.get())

    });
})

//在webpack.config.js中
 output: {
        chunkFilename: "dist/js/[name].chunk.js"//延迟加载的模块名字
    },

chunkFilename一定要写,不写你打包出来的文件不存在于项目中,不知道在哪,你会看到这样的提示

image

最后说一下加载字符串,用模板渲染
这里要用到html-loader
模板文件

//info.html
<div class="">
    <h1>我是标题</h1>
    <ul>
        <li>{{name}}</li>
        <li>{{address}}</li>
    </ul>
</div>
//在main.js这样使用,你也可以使用其它模板
function htmlTpl(tpl, data) {
    return tpl.replace(/{{(\w+)}}/g, function() {
        return data[arguments[1]];
    });

}
var infoTpl = require('../tpl/info.html');
var data = {
    name: "<h3>你好</h3>",
    address: '湖北襄阳'
}
$('#test_tpl').html(htmlTpl(infoTpl,data));

本地服务自动刷新浏览器(webpack-dev-server)
首先安装
npm install webpack-dev-server --save
执行命令
webpack-dev-server --port=3000 --hot --inline
打开localhost:3000 即可访问,改变js文件自动刷新浏览器
--hot和--inline的位置不能颠倒
--hot --inline是一条独立的命令

--content-base <file/directory/url/port>: base path for the content.
--quiet: don’t output anything to the console.
--no-info: suppress boring information.
--colors: add some colors to the output.
--no-colors: don’t use colors in the output.
--compress: use gzip compression.
--host <hostname/ip>: hostname or IP. 0.0.0.0 binds to all hosts.
--port <number>: port.
--inline: embed the webpack-dev-server runtime into the bundle.
--hot: adds the HotModuleReplacementPlugin and switch the server to hot mode. Note: make sure you don’t add HotModuleReplacementPlugin twice.
--hot --inline also adds the webpack/hot/dev-server entry.
--public: overrides the host and port used in --inline mode for the client (useful for a VM or Docker).
--lazy: no watching, compiles on request (cannot be combined with --hot).
--https: serves webpack-dev-server over HTTPS Protocol. Includes a self-signed certificate that is used when serving the requests.
--cert, --cacert, --key: Paths the certificate files.
--open: opens the url in default browser (for webpack-dev-server versions > 2.0).
--history-api-fallback: enables support for history API fallback.

因为命令太长,我们优化一下
在package.json里面写上

"scripts": {
    "start-server":"webpack-dev-server --port=3000 --hot --inline"
  },

我们就可以使用 npm run start-server 来执行这条命令了
tips:

  1. 使用webpack-dev-server 编译后的文件存内存中,本地看不到,仅作为调试用
  2. 在webstorm中会有失效的情况,需要设置一下(将System Setting - safe write勾掉就好)

相关链接
webpack指南
一小时包教会 —— webpack 入门指南
webpack工具迁移
webpack expose-loader exports-loader区别
webpack从开发到上线
用UglifyJS2合并压缩混淆JS代码

#2016-09-02

实用在线地址

在线二维码生成

http://cli.im/

在线编辑代码

http://jsbin.com/
http://jsfiddle.net/

在线Markdown编辑

http://mahua.jser.me/

谷歌记事本

地址栏输入data:text/html, <html contenteditable>

在线CSS校验

http://jigsaw.w3.org/css-validator/#validate_by_uri

格式化javascript

http://jsbeautifier.org/

正则表达式校验

http://tool.oschina.net/regex
http://refiddle.com/#play(有颜色)
https://regex101.com/

在线代码对比

https://www.diffchecker.com/diff

图片压缩

https://tinypng.com/

常用CSS代码集合

http://linxz.github.io/tianyizone/

animate.css

http://daneden.github.io/animate.css/

谷歌页面性能检测

https://developers.google.com/speed/pagespeed/insights/

CSS三角形生成器

http://apps.eky.hk/css-triangle-generator/zh-hant

loading 在线制作

http://cssload.net/
https://connoratherton.com/loaders

图片转换成SVG格式

http://image.online-convert.com/convert-to-svg

CSS弹窗动画

http://tympanus.net/Development/ModalWindowEffects/

番茄工作法

http://alloyteam.github.io/AlloyTimer/

HTMLToJavaScript字符串

http://www.css88.com/tool/html2js/

常用代码片段

http://snippets.barretlee.com/#!/snippets/javascript/javascript-keycodes.snippet

数据结构和算法动态可视化

http://zh.visualgo.net/

百度脑图

http://naotu.baidu.com/

MD5在线解密

http://www.cmd5.com/

在线检查文件是否有病毒

https://www.virustotal.com/
http://www.virscan.org/

PSD-TO-HTML

http://jhtmls.com/h5psd/
npm地址 https://www.npmjs.com/package/h5psd

图标素材搜索

http://www.iconpng.com/

LOGO在线制作

http://www14.flamingtext.com/All-Logos/page2

#2016-02-16

懂点bat命令

打开某个文件夹 执行某个命令

//启动数据库
::D:\Program Files\MongoDB\Server\3.0\bin>mongod --dbpath "D:\raclen\raclen\data"
@echo off
echo mongod start
D:
cd \Program Files\MongoDB\Server\3.0\bin
mongod --dbpath "D:\raclen\raclen\data"
D:
cd \H5Static\
grunt 

批处理常用命令总结 - 批处理命令简介

#2017-09-30

async流程控制

写爬虫的时候会用上
代码都是异步执行,也是个麻烦事。
当for循环中执行函数,是异步的,就会出现问题,上次用了一个很蹩脚的办法,把循环改成定时器

$.each(function (i, item) {
    self.core(item, backfun); //异步函数
});

改成了这样

var count = 0;
var timeout1 = setInterval(function () {
    if (count == arr.length) {
        clearInterval(timeout1);
        return;
    }
    var index = count % arr.length;
    self.core(arr[index], backfun);
    count++;
}, 1000);

这样还是不好,下面用async来控制流程....
使用到了async.eachSeries,注意它的第二个函数,不光是用来处理错误的,也是回调的,有了它就可以连起来了

async.eachSeries(arr, function (item, callback) {
    console.log(item)
    self.core(item, function ($) {
        var $itemlist = $('.post-listing .item-list');
        var linkList = $itemlist.map(function (idx, element) {
            var $element = $(element).find('.post-title a');
            return $element.attr('href');
        }).get();
        console.log(linkList)
        async.eachSeries(linkList, function (item, callback2) {
            self.core(item, function ($) {
                var author = $('.post-inner .entry').find('p').eq(0).text();
                var content = $.html('.article_text');
                var text = $('.post-inner span[itemprop="name"]').text();
                console.log("text=" + text);
                if ( !! text) {
                    var thor = new articlema({
                        title: text,
                        author: author,
                        category: '002',
                        content: content
                    });
                    thor.save(function (err, thor) {
                        if (err) return console.log(err);
                        //console.log(thor);
                    });
 
                }
                sleep(500)
                callback2(null)
            });
        }, function (err) {
            console.log("content==============" + err);
            sleep(500)
            callback(null)
        });
    })
 
}, function (err) {
    console.log("item==============" + err);
})


image

#2016-02-04

antd 实现keep alive

背景:后台项目需要切换路由的时候保存用户数据
就琢磨着怎么实现
antd pro项目
gitbub找了个钩子

npm install react-live-route --save-dev

找到这个文件
BasicLayout.js

   {getRoutes(match.path, routerData).map(item => (
                    <AuthorizedRoute
                        key={item.key}
                        path={item.path}
                        component={item.component}
                        exact={item.exact}
                        authority={item.authority}
                        redirectPath="/exception/403"
                    />
                ))}

修改为

<ScrollToTop>
                {getRoutes(match.path, routerData).map((item, index) => {
                  return (<LiveRoute path={item.path} key={index} alwaysLive={needAlwaysLive} component={item.component} />)
                })}
</ScrollToTop>

ScrollToTop.js
切换的时候定位到顶部

import { withRouter} from 'dva/router';
import React, { Component } from 'react';
class ScrollToTop extends Component {
  componentDidUpdate(prevProps) {
    if (this.props.location !== prevProps.location) {
      window.scrollTo(0, 0)
    }
  }

  render() {
    return this.props.children
  }
}

export default withRouter(ScrollToTop)

#2018-12-06

DOM操作——怎样添加、移除、移动、复制、创建和查找节点

  1. 创建新节点
    createDocumentFragment() //创建一个DOM片段
    createElement() //创建一个具体的元素
    createTextNode() //创建一个文本节点
  2. 添加、移除、替换、插入
    appendChild()
    removeChild()
    replaceChild()
    insertBefore()
  3. 查找
    getElementsByTagName() //通过标签名称
    getElementsByName() //通过元素的Name属性的值
    getElementById() //通过元素Id,唯一性
    本节要用到的html例子
 <ul id="myList">
    <li>项目一</li>
     <li>项目二</li>
   <li>项目三</li>
 </ul>

1.创建元素节点
document.createElement() 方法 用于创建元素,接受一个参数,即要创建元素的标签名,返回创建的元素节点

var div = document.createElement("div");  //创建一个div元素
div.id = "myDiv";        //设置div的id
div.className = "box";    //设置div的class

创建元素后还要把元素添加到文档树中
2.添加元素节点
appendChild() 方法 用于向childNodes列表的末尾添加一个节点,返回要添加的元素节点

var ul = document.getElementById("myList");    //获得ul
var li = document.createElement("li");         //创建li
li.innerHTML = "项目四";                    //向li内添加文本
ul.appendChild(li);                //把li 添加到ul子节点的末尾

添加后:

 <ul id="myList">
     <li>项目一</li>
     <li>项目二</li>
     <li>项目三</li>
    <li>项目四</li>
 </ul>

appendChild() 方法还可以添加已经存在的元素,会将元素从原来的位置移到新的位置

1 var ul = document.getElementById("myList"); //获得ul
2 ul.appendChild(ul.firstChild); //把ul的第一个元素节点移到ul子节点的末尾
运行后(IE):

 <ul id="myList">
     <li>项目二</li>
     <li>项目三</li>
     <li>项目一</li>
 </ul>

insertBefore() 方法 ,如果不是在末尾插入节点,而是想放在特定的位置上,用这个方法,该方法接受2个参数,第一个是要插入的节点,第二个是参照节点,返回要添加的元素节点

 var ul = document.getElementById("myList");    //获得ul
 var li = document.createElement("li");         //创建li
 li.innerHTML= "项目四";                    //向li内添加文本
 ul.insertBefore(li,ul.firstChild);        //把li添加到ul的第一个子节点前

添加后:

 <ul id="myList">
     <li>项目四</li>
     <li>项目一</li>
     <li>项目二</li>
      <li>项目三</li>
 </ul>
var ul = document.getElementById("myList");    //获得ul
var li = document.createElement("li");         //创建li
li.innerHTML= "项目四";               //向li内添加文本
ul.insertBefore(li,ul.lastChild);        //把li添加到ul的子节点末尾

添加后:

 <ul id="myList">
     <li>项目一</li>
     <li>项目二</li>
     <li>项目三</li>
     <li>项目四</li>
 </ul>
var ul = document.getElementById("myList");    //获得ul
var li = document.createElement("li");         //创建li
li.innerHTML= "项目四";                    //向li内添加文本
var lis = ul.getElementsByTagName("li")   //获取ul中所有li的集合
ul.insertBefore(li,lis[1]);            //把li添加到ul中的第二个li节点前

添加后:

 <ul id="myList">
     <li>项目一</li>
     <li>项目四</li>
     <li>项目二</li>
     <li>项目三</li>
 </ul>

3.移除元素节点
removeChild() 方法 ,用于移除节点,接受一个参数,即要移除的节点,返回被移除的节点,注意被移除的节点仍然在文档中,不过文档中已没有其位置了

 var ul = document.getElementById("myList");            //获得ul
 var fromFirstChild = ul.removeChild(ul.firstChild);    //移除ul第一个子节点
 var ul = document.getElementById("myList");    //获得ul
 var lis = ul.getElementsByTagName("li")        //获取ul中所有li的集合
 ul.removeChild(lis[0]);                  //移除第一个li,与上面不同,要考虑浏览器之间的差异

4.替换元素节点
replaceChild() 方法 ,用于替换节点,接受两个参数,第一参数是要插入的节点,第二个是要替换的节点,返回被替换的节点

 var ul = document.getElementById("myList");            //获得ul
 var fromFirstChild = ul.replaceChild(ul.firstChild);    //替换ul第一个子节点
 var ul = document.getElementById("myList");    //获得ul;
 var li = document.createElement("li");         //创建li
 li.innerHTML= "项目四";                    //向li内添加文本
 var lis = ul.getElementsByTagName("li")        //获取ul中所有li的集合
 var returnNode = ul.replaceChild(li,lis[1]);   //用创建的li替换原来的第二个li

5.复制节点
cloneNode() 方法,用于复制节点, 接受一个布尔值参数, true 表示深复制(复制节点及其所有子节点), false 表示浅复制(复制节点本身,不复制子节点)

 var ul = document.getElementById("myList");    //获得ul
 var deepList = ul.cloneNode(true);            //深复制
 var shallowList = ul.cloneNode(false);        //浅复制

原文地址节点的操作 创建、添加、移除、移动、复制

#2016-05-17

多说评论机器人

捣鼓了一个自动评论的东西,基于nodejs
主要代码

var Faker = require('faker-zh-cn');//随机生成中文名字
var request = require("request");
//多说评论
function autoDuoShuo() {
    var options=cloneObj(defOptions);
    var randomName = Faker.Name.findName();
    var email = Math.random().toString(8).substr(5);
    var submit = {
        thread_id: "1317975792122068993",
        parent_id: "",
        nonce: "568c7ef40c80c",
        message: "佛祖说"+randomName,
        author_name: randomName,
        author_email:email + "@163.com",
        v:"15.11.15"

    }
    var j = request.jar();
    var url_duoshuo = 'http://xxxx.duoshuo.com/api/posts/create.json';
    options.url = url_duoshuo, options.jar = j, options.method = 'POST', options.headers.Cookie = "duoshuo_unique=2f423fba75c68a2a";
    options.headers.Referer = "http://xxxxxx/message.html";
    options.headers.Host = "xxxxxx.duoshuo.com";
    options.headers.Origin = "http://xxxxxx";
    options.headers["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8";
    options.form = submit;
    options.headers.Accept = "*/*";
    console.log(options);
    request(options, function (error, response, body) {
        console.log("autoDuoShuo=" + response.statusCode)
        if (!error && response.statusCode == 200) {
            console.log(body);
            sleep(1000);
            autoDuoShuo();
        }
    });
}

仅供学习之用,勿过分*扰他人

#2016-02-04

多说已经不在了 #2019-09-15

随手写了一个gulp插件

作用就是把px转换成rem,今天加班收获不少O(∩_∩)O哈哈~

image

var through = require('through2');
module.exports = function () {
    return through.obj(function (file, enc, cb) {
        if (file.isNull()) {
            this.push(file);
            return cb();
        }

        if (file.isStream()) {
            this.emit('error', new gutil.PluginError(PLUGIN_NAME, 'Streaming not supported'));
            return cb();
        }
        var reg=/(\d+)px/ig;
        function med(){
            var s1=arguments[1];
            return parseFloat(s1)/100+'rem'
        }
        var content=file.contents.toString().replace(reg,med);
        file.contents = new Buffer(content);

        this.push(file);

        cb();
    });
};

file.contents.toString()这句话的意思就是获取文件的内容,然后转换成字符串

放在这https://github.com/ralcen/jsCode/blob/master/gulp_bulid/gulp-pxtworem.js
为了匹配小数的情况,更新了一下正则表达式
var reg = /(\d+\.\d+)px|(\d+)px/ig;
med函数也有所更改,具体看github里面的代码

#2015-07-12

正则表达式积累

将数字和. 之外的清除

onkeyup='this.value=this.value.replace(/[^\d.]/gi,"")'

()的用法

var str2=str.match(/qq:\'\d+\'/);
得到的是一个数组[qq:'2275025']
var str2=str.match(/qq:\'(\d+)\'/);
得到的数组["qq:'2275025'","2275025"]
str2[2]=2275025
()的作用就是在当前匹配的结果中把()的东西,作为数组第二个元素,让你可以获取

\w的用法

我们平常看到了网站用户名注册,就用到了这个
\w=[A-Za-z0-9_] 在正则表达式中,大写和小写,
相反,比如\D表示非数字,\d表示数字,\W=[^A-Za-z0-9_],说到这,我们可以知道[^是取反的意思(^是匹配开始)
正则表达式中,元字符需要转义,例如(),转义,用\这个我们都知道

[] 中括号的用法

在中括号中,我们可以这样写[123 )]
这个表示是1或者2或者3或者空格或者),在中括号中,元字符好像不需要转义

|的用法

|表示或者的意思,通常我们需要匹配的可能有几个就可以|,比如身份证号,最后一位可能是数字,也可能是X,这里我们就可以用到|

*?+

*——0到多个
?——0到1个
+——1到多个

身份证正则

/^(\d{6}[1,2]\d{3}[0,1]\d{7}|\d{6}[1,2]\d{3}[0,1]\d{6}(\d|X|x))$/

数字逗号分隔

    var strNum='67788889999';
    var strNumn=strNum.split('').reverse().join('').replace(/(\d{4})/g,'$1 ').replace(/\,$/,'').split('').reverse().join('');
    console.log(strNumn);
    //这个还可以这样写
    function thousand(str){
          return str.replace(/(?!^)(?=([0-9]{3})+$)/g,',');
    }
console.log(thousand(str));//"1,234,567,890"
console.log(thousand("123456"));//"123,456"
console.log(thousand("1234567879876543210"));//"1,234,567,879,876,543,210"
//这个正则也可以
var f2 = '99999999999'.replace(/\d{1,3}(?=(\d{3})+$)/g, '$&,');
//对于有小数的
var f = '99999999999.02'.replace(/\d{1,3}(?=(\d{3})+(?:\.\d{1,2})?$)/g, '$&,');
//toLocaleString竟然就可以达到这个效果	
var str = "1234567890";
(+str).toLocaleString();//"1,234,567,890"
"420684199206554016".replace(/(\d{3})(?!$)/g,'$&,')
"420,684,199,206,554,016"

这说一下replace里面约定$用法
image

$(1-99) 是捕获的文本 $&amp;是匹配的文本

//限制输入8个字符,相当于maxLeng=8

var t=/^[A-Za-z0-9|\u4e00-\u9fa5]{8}/;
document.getElementById('key').onkeyup = function(){
    var self =this.value;
    this.value = t.test(self)?self.match(t):self;
    }

在使用过程中,我们可能会匹配多个,match 在这里就不好用了
我们可以使用exec,这里是例子是匹配字符串中所有的src链接,因为javascript不支持反向零宽断言,好像只能用捕获的方式来写,注意在下面result和p要先定义出来,写在while里面会死循环

var str = '';
var result;
var p = /src="(.*?)"/g;
while (result = p.exec(str)){
        console.log(result[1])
}

扩展阅读

正则表达式前端使用手册
javascript正则表达式---正向预查

#2014-07-18

关于感冒

有几年没感冒了,最近又感冒了,感觉我每次感冒都症状都一样,发热,浑身无力
现在的我已经可以通过搜索引擎来弄懂一个东西了,现在来了解下这个感冒
首先感冒是经常的事情,大多是病毒性引起,不需要吃药,我也没吃过,但是我每次都比较严重
下面这些药可以缓解感冒症状
image
普通感冒不需要打吊瓶,可以慢慢好,但是由于感冒可能会出现细菌性感染,血常规,白细胞偏高,就需要打吊瓶了,这时候你可能需要使用抗生素
下面介绍下三种抗生素 青霉素 头孢菌素 阿奇霉素

青霉素 在我的记忆里不多 好像就小时候用过

值得一说的就是头孢,他还有名字先锋
image
更多介绍 https://zh.wikipedia.org/wiki/%E9%A0%AD%E5%AD%A2%E8%8F%8C%E7%B4%A0

阿奇霉素
维基百科地址 https://zh.wikipedia.org/wiki/%E9%98%BF%E5%A5%87%E9%9C%89%E7%B4%A0

这些都是一些学术说明,下面是通过其他地方得到的细节,
使用头孢会增加耐药性,头孢相对阿奇霉素便宜,使用头孢和青霉素一样要先皮试,不良反应会造成休克的
使用阿奇霉素增加耐药性平缓 ,价格比头孢高,无不良反应,需要先皮试,经过本人和知乎网友测试,同一个手打两次(连续三天,第三天有只手就要打两次了)会很疼,非常疼
我看了下 它们发现的时间 阿奇霉素晚于头孢晚于青霉素,阿奇霉素是一种比较新的抗生素

字符串还可以这样玩

var tpl = ['{{name}}',
            '<p>我来自{{address}}</p>',
            '<p>这是我的个人博客</p>',
        ].join("");

        var data = {
            name: "<h1>你好</h1>",
            address: '湖北襄阳'
        }
        var html = tpl.replace(/{{name}}/, data.name).replace(/{{address}}/, data.address);
        document.body.innerHTML = html

这像什么,模板赋值啊,忽然发现一个新大陆,有意思
现在我把它改进了下

var tpl = ['{{name}}',
            '<p>我来自{{address}}</p>',
            '<p>这是我的个人博客</p>',
        ].join("");

        var data = {
            name: "<h1>你好</h1>",
            address: '湖北襄阳'
        }
        function htmlTpl(tpl,data){
            return tpl.replace(/{{(\w+)}}/g,function(){
                return data[arguments[1]];
            });

        }
        // var html = tpl.replace(/{{name}}/, data.name).replace(/{{address}}/, data.address);
        document.body.innerHTML = htmlTpl(tpl,data)

顺便说一下,正则的确是很好的工具,有了正则,思路又开阔了些
预览一下

#2016-07-28

javascript数组随机排序

数组随机排序又叫数组洗牌,我们在做一些抽奖的小游戏会用上
可能我从来用不上这个,但是,注意了,打起精神,面试可能会遇上哦

  var arr = [1,5,6,9];

    function shuffle(a){
    	var len = a.length,range;
    	var narr = [];
    	while(len){
    		range = Math.floor(Math.random()*len--);
    		narr.push(arr[range]);
    		arr.splice(range,1);
    	}
    	return narr;

    }
    console.log(shuffle(arr));
    //大神们说这里使用了splice复杂度比较高,那么效率就比较低
    //只有费雪耶茨洗牌才是标准,下面我们试着写写
    function shuffleplus(a){
    	//同样定义几个变量
    	var len = a.length,range;
    	//同样我们来遍历这个数组
    	while(len){
    		//同样我们来获得一个随机数
    		range  = Math.floor(Math.random()*len--);
    		//接下来怎么办呢,让我想想,我记得要换两次位置
    		//先把数组随机的数存下来
    		var temp = a[len];
    		a[len] = a[range];
    		//我不会写了/(ㄒoㄒ)/~~
    		a[range] = temp;

    	}
    	return a;

    }
    console.log(shuffleplus(arr))

延伸阅读
JavaScript 数组乱序
数组的完全随机排列
Fisher–Yates Shuffle
#2016-07-07

Photoshop不改变像素改变大小

切图的时候我们可能会用上精灵图,比如这个
image
但是随着后续需求的增加,那张图片就放不下那么多图标了,就需要改变那个图片的大小,但是图片的像素,以前的图标位置,不能变
我好像一年没用上了,刚试了下,还记得。为了避免忘记了,记录一下
按下 快捷键Ctrl+Alt+C

image

上传后,动图不动了。。。

#2016-06-21

fetch超时处理

antd 升级到umi后,也没有对request做超时处理,很奇怪
因fetch本身不支持超时,这里需要用到Promise.race()方法
Promise.race([p1,p2,p3])
p1,p2,p3哪个快,就得到的是哪个

Promise.race([
fetch(url,options),
 new Promise((resolve, reject)=> {
      setTimeout(()=> reject(new Error('request timeout')), 30000)
    })
]).then((res)=>{
}).catch((e)=>{
})

antd 的request.js 返回值改造成这样

  return Promise.race([
    fetch(url, newOptions),
    new Promise((resolve, reject)=> {
      setTimeout(()=> reject(new Error('request timeout')), 30000)
    })])
    .then(checkStatus)
    .then(response => {
      if (newOptions.method === 'DELETE' || response.status === 204) {
        return response.text();
      }
      return response.json();
    })
    .catch(e => {
      if (e && e.message.match && e.message.match(/timeout/)) {
        notification.error({
          key: 'timeout',
          message: `请求超时`,
          description: ' ',
        });
        return;
      }

      const status = e.name;
      if (status === 403) {
        router.push('/exception/403');
        return;
      }
      if (status <= 504 && status >= 500) {
        router.push('/exception/500');
        return;
      }
      if (status >= 404 && status < 422) {
        router.push('/exception/404');
      }
    });

由于fetch不支持中断,这里只是前端拿到一个超时状态,请求还是会继续,不会中断。

扩展阅读

理解和使用Promise.all和Promise.race

机器注册账号

下面这段代码,用于自动注册账号

//自动注册
function autoReg(){
    var email = Math.random().toString(8).substr(5);
    var pw = Math.random().toString(36).substr(8);
    var pLogin = {
        username: pw,
        password: pw,
        repassword: pw,
        sskey:"salanghae",
        email: email + "@163.com"
    };
    var j = request.jar();
    var url_register = 'http://third-contact.com/ss/Account/User/register';
    options.url=url_register,options.jar=j,options.method= 'POST', options.headers.Cookie="__session:0.9360456641297787:=http:;thinkphp_show_page_trace=0|0; PHPSESSID=c1kr9fes4lfjh044svdup3t183";
    options.headers.Referer="http://third-contact.com/ss";
    options.headers.Host="third-contact.com";
    options.headers["X-Requested-With"]= "XMLHttpRequest"
    options.headers.Origin="http://third-contact.com"
    options.headers["Content-Type"]="application/x-www-form-urlencoded; charset=UTF-8";
    //console.log(options);
    options.form=pLogin;
    request(options, function (error, response, body) {
        console.log("login2="+response.statusCode)
        if (!error && response.statusCode == 200) {
            console.log(body);
            //sleep(500)
            //autoReg()
        }
    });
}

测试可用,仅供学习http之用

#2016-02-04

认识vue

关注Vue也很久了,第一次知道它,对它的印象是小,只有18K。
下面通过这几个例子来介绍它,基于目前最新版本的vue2.X

image

https://github.com/raclen/jsCode/tree/master/vuejs
tips
有的时候 不光模板里面需要用到props里面的值,在methods里面也需要用到,在这我们就可以初始化props的值

props: ['initialCounter'],
data: function () {
  return { counter: this.initialCounter }
}

定义一个计算属性,处理 prop 的值并返回。
这个也很好用,比如服务端给的数据为
"value": "[\"老人身份证\",\"残疾人证\",\"导游资格证\"]",
我们需要对这个value处理一下 在显示,就可以使用以下代码
在模板里面这样写{{normalizedSize}}

props: ['size'],
computed: {
  normalizedSize: function () {
    return this.size.trim().toLowerCase()
  }
}

下面是vue生命周期
image


非父子组件通信
var bus = new Vue()

// 触发组件 A 中的事件
bus.$emit('id-selected', 1)

// 在组件 B 创建的钩子中监听事件
bus.$on('id-selected', function (id) {
// ...
})
computed用于计算属性(当前data没有某个值,计算出一个值后,取法就像去data里面的值)
用过一段时间vue你可能会发现 短时间内改变某个值无效
这是vue的Tick机制,我们可以这样写

Vue.component('example', {
  template: '<span>{{ message }}</span>',
  data: function () {
    return {
      message: 'not updated'
    }
  },
  methods: {
    updateMessage: function () {
      this.message = 'updated'
      console.log(this.$el.textContent) // => '没有更新'
      this.$nextTick(function () {
        console.log(this.$el.textContent) // => '更新完成'
      })
    }
  }
})

整体感觉,语法丰富灵活,生态好(比react中文资料多,相比较angular2,提起来的不多了),没有编译模板之类,入门容易,还是觉得有点随意,0.9->1.X->2.X都变化很大,不向下兼容,对后期维护人员不友好

参考链接

深入响应式原理
vue-router 60分钟快速入门
vue中文文档
https://router.vuejs.org

扩展阅读

自定义事件
详解vue的数据binding原理
Vue学习:生命周期

#2017-01-03

node中request模块配置项

var options = {
    url: '',
    encoding: "utf-8",
    headers: {
        "Connection": "keep-alive",
        "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
       // 'Cookie':'userid=123456; mycookie2=abcdefg',
        "Accept-Encoding": "gzip, deflate, sdch",
        "Accept-Language": "zh-CN,zh;q=0.8",
        "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2603.0 Safari/537.36"
    },
    json: true
};

设置method
options.method= 'GET'
设置referer
options.headers.Referer=referer;
request默认是不支持cookies,需要开启
var j = request.jar();options.jar=j
这是操作cookies的一个例子

//格式化cookies
function formatCookies(c) {
    var cookies = {};
    var pairs = c.split(/[;,] */);
    for (var i = 0; i < pairs.length; i++) {
        var idx = pairs[i].indexOf('=');
        var key = pairs[i].substr(0, idx);
        var val = pairs[i].substr(++idx, pairs[i].length).trim();
        cookies[key] = val;
    }
    return cookies;
}

app.get('/ptqrshow', function (req, res, next) {
    var j = request.jar();
    var url = "";
    var referer = "";
    options.url=url,options.jar=j,options.method= 'GET',options.headers.Referer=referer;
    request(options, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            var cookie_string = j.getCookieString(url);
            //console.log(cookie_string);
            var item = {
                cookies: cookie_string,
                url: 'image/doodle.png'
            };
            res.send(item)
        }
    }).pipe(fs.createWriteStream('./public/image/doodle.png'));;
});

如果需要传参数,可以使用form,例如

options.form={r:{"ptwebqq":cookies.ptwebqq,"clientid":53999199,"psessionid":"","status":"online"}};

设置代理(这样可以使用fiddler抓取请求了)
proxy: "http://127.0.0.1:8888", //for fiddler
抓取被墙的网站:

request({url:"https://www.facebook.com/",proxy:"http://127.0.0.1:1084"}, function (error, response, body) {
    console.log("proxy="+response.statusCode)
    if (!error && response.statusCode == 200) {
        console.log(body);
    }
});//1084 is ss proxy

request文档地址

.gitignore

在使用git的时候,我我们可能会遇到,位于仓库中的某些文件夹不需要提交,我们可以对其过滤
这时候就用到.gitignore
在仓库中新建一个.gitignore的文件。
在window中创建这个文件可能会弹出请输入键名,
可以在进入git仓库后输入touch .gitignore 就创建这个文件了
如果要匹配所有目录下的 node_modules 文件夹,只需要这样做:
node_modules/
把需要过滤的文件夹名字写到里面就行了,如果有多个,换行写入
相关链接
gitignore 文件的正确用法

认识Handlebars

Handlebars是一个模板

    var tpl2='\
    <ul class="list_top layoutfix">\
    <li class="w_01">名称</li>\
    <li class="w_02">原价</li>\
    <li class="w_03">111</li>\
    <li class="w_04">优惠</li>\
    <li class="w_05">{{age}}</li>\
    </ul>\
    ';
    var html = Handlebars.compile(tpl2)({'age': 12});
    document.body.innerHTML = html;

你可以自定义方法,让它变成和angular一样灵活

//相等
Handlebars.registerHelper('equal', function (a, b, v1, v2) {
                return a == b ? v1 : v2;
            });
//或者这样,它就像一个过滤器
Handlebars.registerHelper('regcheck', function (a) {
                var reg = {
                    "1": "checkIdCard",
                    "2": "checkPassport",//护照
                    "10": "checkHKCard",//港澳通行证
                    "22": "checkTAIWAN",//**通行证
                    "6": "checkDriver"//驾驶证
                };
                return !!reg[a] ? reg[a] : "checkCard";

            });
 //还可以这样
// if增强 {{#ifPlus var1 '==' var2}}
Handlebars.registerHelper('ifPlus', function(v1, operator, v2, options) {

        switch (operator) {
            case '==':
                return (v1 == v2) ? options.fn(this) : options.inverse(this);
            case '===':
                return (v1 === v2) ? options.fn(this) : options.inverse(this);
            case '<':
                return (v1 < v2) ? options.fn(this) : options.inverse(this);
            case '<=':
                return (v1 <= v2) ? options.fn(this) : options.inverse(this);
            case '>':
                return (v1 > v2) ? options.fn(this) : options.inverse(this);
            case '>=':
                return (v1 >= v2) ? options.fn(this) : options.inverse(this);
            case '&&':
                return (v1 && v2) ? options.fn(this) : options.inverse(this);
            case '||':
                return (v1 || v2) ? options.fn(this) : options.inverse(this);
            default:
                return options.inverse(this);
        }
    });  
Handlebars.registerHelper('list', function(items, options) {
      var out = "<ul>";
      for(var i=0, l=items.length; i<l; i++) {
        out = out + "<li>" + options.fn(items[i]) + "</li>";
      }
      return out + "</ul>";
});
//还能这样玩,仿佛是组件的雏形
var tpl3 = "{{#list people}}{{firstName}} {{lastName}}{{/list}}";
var data3 ={
  people: [
    {firstName: "Yehuda", lastName: "Katz"},
    {firstName: "Carl", lastName: "Lerche"},
    {firstName: "Alan", lastName: "Johnson"}
  ]
}
var html = Handlebars.compile(tpl3)(data3);
document.body.innerHTML= html;             

有时候 需要传入一段html 我们可以使用{{{三个括号
更多可能等你探索
handlebarapi
handlebar官网

#2016-04-15

家庭药箱的非处方药物清单

twitter上看到一篇文章,就收藏了

  • 布洛芬。 解热,镇痛,抗炎。头痛、经痛时可以缓解,但未知原因的病痛不要用镇痛药掩盖病症
  • 氨酚曲麻(或近似药物)。 治疗感冒症状(替代药物:抗病毒颗粒,莲花清瘟胶囊)
  • 马来酸氯苯那敏。 抗过敏,有过敏体质的人可以用来缓解过敏症状。
  • 盐酸小檗碱。 止泻
  • 开塞露 。治疗便秘,皮肤开裂,甘油成分,润肤。
  • 红霉素软膏。 毛囊炎,皮肤感染,用于烧烫伤,防感染。大面积烧烫伤还是需要去医院处理。
  • 多潘立酮。 治疗消化不良
  • 创可贴、纱布、脱脂棉球、止血带。用处理外伤,大伤口初步处理后还是要去医院缝合。
  • 碘伏。 皮肤消毒,擦伤后需要消毒。
  • 云南白药。 外伤止血,内服有乌头碱中毒风险
  • 0.9% 氯化钠溶液。 清洗伤口或补充盐分,脱水后需要补充盐分,如长跑后和腹泻后。
  • 5% 或 10% 葡萄糖溶液。 补充能量,葡萄糖是单糖可以被人体直接吸收。
  • 薄荷桉油含片。 治疗咽喉肿痛
  • 复方醋酸底色米松乳膏。 治疗皮肤瘙痒
  • 温度计。测量体温。
  • 冰袋。用于冰敷。
  • 藿香正气水。 治疗中暑, 肠胃型感冒。
  • 苯海拉明 。治疗晕车。

扩展阅读

家庭药箱的非处方药物清单

#2016-03-18

git常用命令

clone一个仓库
git clone https://github.com/XXXXXX/jsCode.git
修改的东西添加到仓库
git add . 提交所有文件
git commit -m ‘修改标记’
git pull 更新仓库
git push 提交更新
git branch 查看本地所有分支
git status 查看当前状态
git branch -a 查看所有的分支
git checkout -b dev 建立一个新的本地分支dev
git merge origin/dev 将分支dev与当前分支进行合并
git checkout dev 切换到本地dev分支
git rm 文件名(包括路径) 从git中删除指定文件
git rm [文件夹]/* 可以删除文件夹所有文件,然后文件夹不见了
git commit -m “remove” 移除文件(从Git中删除)
git reset --hard HEAD(回退)
删除步骤
1、本地删除
2、git add .
3、git commit -am ‘remove’ 一次性提交
4、git push
回退到某个版本
commit d656b7c8c3f681b779837005c1b882f0ee40f213
git reset --hard d656b7
当提示没有需要提交的的代码的时候
git commit --amend
:x 回车
git push origin HEAD:refs/for/release --no-thin
git push
//设置代理
git config --global http.proxy 'socks5://127.0.0.1:10087'
git config --global https.proxy 'socks5://127.0.0.1:10087'
// 打包自动提交

    "pkg" :"npm run build",
    "prepkg": "git pull",
    "postpkg": "git add -A && git commit -m auto-pkg -n && git push"

// 强推到远程
git reset --hard commit_id 退到/进到 指定commit的sha码
git push origin HEAD --force
在 Git 中 Checkout 历史版本

字体、光和颜色

字体

font-family: 字体名1, 字体名2, 字体名n, 字体系列名;
font-family: Verdana, Helvetica, "Microsoft YaHei", Arial;

1、系统会选择第一个字体,如果没有就用第二个字体,以此类推,所以我们应该在最后一个放一个通用字体,以保证正常显示
2、英文字体名应该放在中文的前面,以保证中英文字体不同
3、如果字体名有空格应该使用双引号
4、中文字体也建议使用英文名,如微软雅黑为Microsoft YaHei,以提高兼容性

字体分为衬线字体和无衬线字体,有人说衬线字体用于表达整体,无衬线字体用于表达个体,很难说哪个好那个不好
扁平化简洁风流行,微软,Google都是用了无衬线字体的logo
Google

光和颜色

颜色有 色相(H) 饱和度(S) 明度(B)
光色的三颜色 红(red)、绿(green)、蓝(blue)它也是网页三颜色
红绿蓝是一种混合后会加色(怎么理解呢,它们混合到一起是白色)
颜色真的是很神奇的东西
我们都知道在CSS中rgb便是颜色

color: rgb(255,255,255);

因为它是加色模式,0最小,255最大,全部255就是相当于红绿蓝混合,也就是白
红和绿混合是什么呢,我们来试一下,颜色值改为rgb(255,255,0);答案是黄
很神奇,如果你想知道颜色混合到一起是什么颜色,可以改里面的值看效果
既然红绿蓝混合越来越白,那我们要得到黑色怎么办,我们什么都不涂不就是黑色了吗
在打印的时候我们在一张白纸上什么都不涂 那就是白色啦
这样就出现了印刷三颜色 青(cyan)、品红(magenta)、黄(yellow)
颜料的三颜色 它是减色模式,混合混合就是变成黑色(但是这个黑不是纯黑,就引入黑(black))
很神奇,为什么红绿蓝是加色。青,品红,黄是减色

参考

Google 换 Logo了!
字体笔记
CSS font-family 网页字体使用小结
色彩设计的原理读书笔记--色彩知识

express post请求res.body 取不到数据

使用post请求,json格式的时候,req.body=undefind 这里需要使用一个中间件body-parser

var express = require('express');
var bodyParser = require('body-parser');

var app = express();

// see https://github.com/expressjs/body-parser
// 添加 body-parser 中间件就可以了
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());

app.post('/', function (req, res) {
    console.log('req.body', req.body);
    res.send({airead: 'fan'});
});

app.listen(8888);

参考链接
https://cnodejs.org/topic/53c89067c9507b4044b1deaa
https://github.com/expressjs/body-parser

#2015-10-19

google-maps网页api开发

通过下面几个例子,一起走进google maps 网页api开发
PS:我查了下V3的api有的说需要key,有的说不需要key,根据文档貌似是需要key的,但是我们公司的的确没用key(然后访问量起来就挂了)。。,以下的预览地址(服务端环境)会提示需要key,拷贝下来本地运行都是可以的

测试数据坐标是我随便写的,不必纠结北京香山公园怎么定位到上海了

0-初始化一个地图

// initMap就是加载后的回调函数
    // 注意和echart一样mainMapLayer需要给宽度和高度地图才能显示出来
        function initMap() {
            console.log('common in initMap');
            var myOptions = {
                zoom: 11,
                center: new google.maps.LatLng(31.22171, 121.352856),
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };
            var map = new google.maps.Map(document.getElementById("mainMapLayer"), myOptions);
        }
    //PS:谷歌地图这个地址在北京,国内可以正常使用http://ditu.google.cn/maps/api/js

预览地址 :点击访问

1-添加标记

    var myCenter=new google.maps.LatLng(31.22171, 121.352856);

            var myOptions = {
                zoom: 11,
                center: myCenter,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };
            var map = new google.maps.Map(document.getElementById("mainMapLayer"), myOptions);

            var marker=new google.maps.Marker({
                position: new google.maps.LatLng(31.22171, 121.30),
                map: map,
                title:"Hello google Map!"
              });

预览地址:点击访问

1.1-添加多个标记

var myCenter = new google.maps.LatLng(31.22171, 121.352856);

            var myOptions = {
                zoom: 11,
                center: myCenter,
                // mapTypeId: google.maps.MapTypeId.ROADMAP
            };
            var map = new google.maps.Map(document.getElementById("mainMapLayer"), myOptions);
            //地图的标记和地图中心不能太远,否则会看不到
            // var marker = new google.maps.Marker({
            //     position: new google.maps.LatLng(31.22171, 121.30),
            //     map: map,
            //     title: "Hello google Map!"
            // });
            var markers=[];
            var neighborhoods = [{
                lat: 31.22071,
                lng: 121.302800
            }, {
                lat: 31.22111,
                lng: 121.352001
            }, {
                lat: 31.22371,
                lng: 121.392100
            }, {
                lat: 31.22571,
                lng: 121.372856
            }, ];

            for (var i = 0; i < neighborhoods.length; i++) {
                addMarkerWithTimeout(neighborhoods[i], i * 500);
            }

            function addMarkerWithTimeout(position, timeout) {
                window.setTimeout(function() {
                    markers.push(new google.maps.Marker({
                        position: position,
                        map: map,
                        animation: google.maps.Animation.DROP
                    }));
                }, timeout);
            }

预览地址:点击访问

2-添加信息框

var myCenter = new google.maps.LatLng(31.22171, 121.352856);

            var myOptions = {
                zoom: 11,
                center: myCenter,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            };
            var map = new google.maps.Map(document.getElementById("mainMapLayer"), myOptions);

            var marker = new google.maps.Marker({
                position: new google.maps.LatLng(31.22171, 121.30),
                map: map,
                title: "Hello google Map!"
            });
            var contentString = '<div id="content">' +
                '<div id="siteNotice">' +
                '</div>' +
                '<div id="bodyContent">' +
                '<p>我是支持HTML的提示框 </p>' +
                '<input type="button" value="查看路线">' +
                '</div>' +
                '</div>';
            var infowindow = new google.maps.InfoWindow({
                content: contentString
            });
            marker.addListener('click', function() {
                infowindow.open(map, marker);
              });

预览地址:点击访问

2.1-添加多个信息框

var myCenter = new google.maps.LatLng(31.22171, 121.352856);

            var myOptions = {
                zoom: 11,
                center: myCenter,
                // mapTypeId: google.maps.MapTypeId.ROADMAP
            };
            var map = new google.maps.Map(document.getElementById("mainMapLayer"), myOptions);

            var neighborhoods = [{
                lat: 31.22071,
                lng: 121.302800,
                title:"上海迪士尼",
                content :"**上海市黄浦区方浜中路280号。"
            }, {
                lat: 31.22111,
                lng: 121.352001,
                title:"东京迪士尼乐园",
                content :"日本千叶县浦安市舞浜1-1号。"
            }, {
                lat: 31.22371,
                lng: 121.392100,
                title:"北京香山公园",
                content :"北京市海淀区买卖街40号。"
            }, {
                lat: 31.22571,
                lng: 121.372856,
                title:"襄阳古隆中",
                content :"湖北省襄阳市襄城区001县道隆中路6号。"
            } ];

            for (var i = 0; i < neighborhoods.length; i++) {
                addMarkerWithTimeout(neighborhoods[i]);
            }

            function addMarkerWithTimeout(position) {
                markers.push(new google.maps.Marker({
                    position: position,
                    map: map,
                    title:"hello google map"
                }));

            }
            var contentString = '<div id="content">' +
                '<div id="siteNotice">{{title}}</div>' +
                '<div id="bodyContent">' +
                '<p>{{content}} </p>' +
                '<input type="button" value="查看路线">' +
                '</div>' +
                '</div>';
            var infowindow = new google.maps.InfoWindow({
                content: contentString
            });
            var j = 0;
            for (j = 0; j < markers.length; j++) {
                markers[j].index = j;
                google.maps.event.addListener(markers[j], 'click', function() {
                    var that = this;
                    infowindow.setContent(htmlTpl(contentString,neighborhoods[that.index]));
                    infowindow.open(map, that);
                });
            }


        }
        function htmlTpl(tpl, data) {
            return tpl.replace(/{{(\w+)}}/g, function() {
                return data[arguments[1]];
            });

预览地址:点击访问

3-路线导航

var directionsService = new google.maps.DirectionsService();//service用来请求导航数据

            var directionsDisplay;
            directionsDisplay = new google.maps.DirectionsRenderer();//渲染导航数据
            directionsDisplay.setMap(map);
            directionsDisplay.setPanel(document.getElementById("direction-panel"));

            //出行方式选择
            var aRouteWay = document.querySelectorAll('.route_way')[0];
            var aAWay = aRouteWay.querySelectorAll('a');
            aAWay.forEach(function(item){
                item.addEventListener('click',function(){
                    aAWay.forEach(function(item2){
                        item2.className="";
                    })
                    this.className="current";
                    var way = this.dataset.way.toUpperCase();
                    calcRoute(way);
                })
            })
            function calcRoute(way) {
              var start = document.getElementById('start_point').value;
              var end = document.getElementById('end_point').value;
              var request = {
                origin: start,
                destination: end,
                travelMode: google.maps.DirectionsTravelMode[way]
              };
              directionsService.route(request, function(response, status) {
                if (status == google.maps.DirectionsStatus.OK) {
                  directionsDisplay.setDirections(response);
                }
              });
            }

预览地址 :点击访问

3.1-多标记路线导航

代码太长,我就直接放地址吧
预览地址:点击访问

3.2-多标记和路线导航分离

预览地址:点击访问

相关链接

google maps 文档地址

使用触摸事件判断滑动方向

  1. 找到触摸之前横纵坐标
  2. 找到触摸之后横纵坐标
  3. 相减得到滑动的距离,如果横着长度大于竖着长度,就是左右滑动,再根据正负可以判断是左还是右,反之,同理可得,是上还是下
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>判断滑动方向</title>
</head>
<style>
    html{
        height: 100%;
    }
    body{
        height: 100%;
        background-color: #f47500;
    }
</style>
<body>

</body>
<script>
    var touchStartClientX,touchStartClientY, direction;
    document.addEventListener('touchstart',function(e){
        touchStartClientX= e.touches[0].clientX;
        touchStartClientY=e.touches[0].clientY;
        //console.log(touchStartClientX+','+touchStartClientY);
    })
    document.addEventListener('touchend',function(e){
        var touchendClientX,touchendClientY;
        touchendClientX= e.changedTouches[0].clientX;
        touchendClientY=e.changedTouches[0].clientY;
        //console.log(touchendClientX+','+touchendClientY);
        var sx=touchendClientX-touchStartClientX;
        var sy=touchendClientY-touchStartClientY;
        console.log(sx+','+sy);
  /*      if(Math.abs(sx)>Math.abs(sy)){
            if(sx>0)
                direction='right';
            else
                direction='left';
        }else{
            if(sy>0)
                direction='down';
            else
                direction='up';
        }*/
        direction=Math.abs(sx)>Math.abs(sy)?(sx>0?'right':'left'):(sy>0?'down':'up');
        alert('direction='+direction);
    })
</script>
</html>

效果预览:http://output.jsbin.com/wuqilofoyi 需要谷歌浏览器模拟一下手机看

#2015-08-28

Gulp-前端自动化工具

这个东西也看了很多遍了,今天写个东西,因为大家都提倡资源优化(最小化),压缩图片,我经常要用到,以前都是用tinypngy一个个压缩,然后保存,现在就用gulp写一个图片的压缩。
首先默认你已经安装node
更改一下npm的镜像,国内的下载npm插件,容易失败(如果你可以正常下载,可以跳过了)

npm config set registry https://registry.npm.taobao.org
// 配置后可通过下面方式来验证是否成功
npm config get registry
Installing Gulp

安装Gulp的过程十分简单。首先,需要在全局安装Gulp包:
npm install -g gulp
然后,在项目里面安装Gulp:
比如cd D:\git\jsCode\gulp_bulid
npm install --save-dev gulp
然后安装一堆插件,有人把它比如成外挂,好吧,都是外挂,DNF连发外挂
D:\git\jsCode\gulp_bulid>npm install --save-dev gulp-imagemin gulp-minify-css gu
lp-uglify gulp-jshint gulp-concat(具体有什么用,谷歌去)
如果以后还想安装插件就是用npm install --save-dev gulp-cache(插件名称)命令
现在要使用的就是gulp-imagemin
在项目根目录新建一个gulpfile.js,名称可以使用其它的吗,我也不清楚,跟我关系不大,忽略

/**
 * Created by XIAODI001 on 2015/3/6.
 * gulp
 */
console.log('begin ...');
var gulp = require('gulp');


/**
 * 需要使用什么插件当然要先引入它的模块啦
 */
var imagemin = require('gulp-imagemin'),
    notify = require('gulp-notify');//提示信息
/**
 * 一般事件的定义放在事件调用的上面,这里我们也把'任务'写到前面
 * 下面是一个压缩图片的任务(task)
 */
gulp.task('img',function(){
    return gulp.src('src/img/event_life/*')
        .pipe(imagemin({
            progressive: true

        }))
        .pipe(gulp.dest('./dest/img/event_life'))
        .pipe(notify({ message: 'img task ok' }));

});
/**
 *gulp 命令会执行defalut
 *我们只需要把要执行执行的函数都放在这个函数(或者事件,就像jquery的ready)里面
 *
 */
gulp.task('default',function(){
    console.log('common in default');
    gulp.run('img');

})
console.log('end ...');//

然后运行 gulp
激动人心的时刻来了
压缩完毕了,提交git出了问题,只有gulpfile.js提交成功了,其它的没add进去
The file will have its original line endings in your working directory.
No such file or directory
搜了搜有的说是版本问题,有的说不用管,不影响提交(瞎说)。。。
然后我准备换了一个GIT仓库,就把代码复制过去,我一看70M,我想我一个免费用户是不是不会给我这么大空间,就把node_modules过滤了,就提交成功了
相关代码https://github.com/ralcen/jsCode/tree/master/gulp_bulid
以上代码压缩力度不够,加上了imagemin-pngquant插件更给力了
//update 2016/10/31
从网易拷过来的额,下面的链接失效了
gulp-html-import//用来导入header和footer
gulp-uncss 可以用来剔除多余的css
gulp-uncss示例

#2015-02-04

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.