Question
|
|
在日常开发中,常常需要用到图片验证码,点击验证码需要更换图片验证码,但因为浏览器会有缓存机制,从后台接口/member/getCaptcha
的图片因为src属性不变所以再次点击触发不会更新,那么如何实现点击再次从后台获取?
Answer
思路:src路径唯一,点击触发不会更新,那么可利用地址后?接参数随机实现
实现:在后台接口地址 + 随机数 即可实现点击更换图片验证码
|
|
|
|
在日常开发中,常常需要用到图片验证码,点击验证码需要更换图片验证码,但因为浏览器会有缓存机制,从后台接口/member/getCaptcha
的图片因为src属性不变所以再次点击触发不会更新,那么如何实现点击再次从后台获取?
思路:src路径唯一,点击触发不会更新,那么可利用地址后?接参数随机实现
实现:在后台接口地址 + 随机数 即可实现点击更换图片验证码
|
|
最近练习Vue,看到官方文档中的嵌套路由,
不做不知道,实在是太坑了,网上资料demo少之又少,然后自己就做了一个demo,用了vue2.0嵌套路由实现豆瓣电影分页功能,供大家学习学习,写得不好望见谅。
官方文档给出的demo:http://jsfiddle.net/yyx990803/L7hscd8h/
主路由:Top250(charts),正在热映(hot),即将上映(ing),新片榜(newmovie)
const router = new VueRouter({
routes: [
{
path: '/', //设置默认路由为Top250
component: charts
},
{
path: '/charts', //Top250
component: charts
},
{
path: '/hot',
component: hot
},
{
path: '/ing',
component: ing
},
{
path: '/newmovie',
component: newmovie
},
]
}
在top250(charts)上添加了分页功能作为子路由,在配置上添加:
{
path: '/charts/:id', //子路由
component: charts,
children: [
{path: 'one', component: ing},
{path: 'two', component: newmovie},
{path: 'three', component: test}
]
}
在charts组件上添加入口:
<router-link to="/charts/1/one">1</router-link>
<router-link to="/charts/1/two">2</router-link>
<router-link to="/charts/1/three">3</router-link>
在charts组件上添加出口:
<router-view></router-view>
<router-link to="/charts/1/one"></router-link>
一定要加上这个1,对应→path: ‘/charts/:id’中的指定id,缺少id是不行的,官方文档有介绍:动态路由配置
demo截图:
分页1:
分页2:
分页3:
跳到正在热映:
demo地址:https://github.com/liangxiaoxin/doubandemo
数据来自豆瓣电影API。
代码写得好烂,凑合着看吧,反正子路由还是成功的啊!哈哈哈
这段时间,一直都是用node的稳定版本,最近因为工作需要,需要用到其他node版本,Google搜了一下,有很好的一个解决方案,选择node版本管理工具,轻松切换node。有两个很好的node版本工具, nvm
和 n
,那么问题来了,选择哪一个呢?
废话,当然是哪个好用就用哪个嘛!
虽然热度 nvm
比 n
高一点,无意中看到FED写的一篇blog《管理 node 版本,选择 nvm 还是 n?》,觉得 n
比较简单易用,然后就毫不犹豫地选择了 n
,全局安装之后输入命令就可以无缝切换了。
n
github地址: https://github.com/tj/n
nvm
github地址:https://github.com/creationix/nvm
$ npm install -g n
下载完成后就可以使用 n
了。
$ n 版本号
下载最新版本
$ n latest
删除某个版本
$ n rm 4.4.4
查看当前 node 版本
$ node -v
切换版本
$ n
6.9.4
ο 7.4.0
4.4.4
以指定的版本来执行脚本
$ n use 7.4.0 index.js
seajs.use("../static/lucky/src/main");
main.js可以省略后缀require('./data');
sea.js官网:http://seajs.org/docs/
define(function(require,exports,module){});
require.async(模块)
seajs.config({
base: "../sea-modules/", //基础目录
alias: { //设置别名
"jquery": "jquery/jquery/1.10.1/jquery.js",
"jquery-easing": "jquery/easing/1.3.0/easing.js"
}
});
seajs.use('a')
seajs.use('x');
优先匹配alias 和 paths,匹配上了不匹配base配置shim :垫片
2:将该别名进行垫的操作,告诉requirejs,我们需要的是文件中的哪一个对象
shim:{ 'jquery':{exports:'$'},[垫其他对象] }
其他配置与seajs差不多
require官方网站:http://requirejs.org/
requirejs官方中文网:http://www.requirejs.cn/
1:<script src> 2:seajs.use([xxx],回调) 3:define(function(require,exports,module){}) 4:var xxx = require(xxx) 5:module.exports = xxx
1:.. 2:requirejs([],回调) 3: define(id,[依赖],回调(参数)) 5:return
requirejs也可以按照cmd的方式
define(function(require,exports,module){})
第三方的问题
if(define typeof === 'function' && define.cmd){ define(function(){return 对象})}
设置paths:{jquery:'路径'}
shim:{'jquery':{exports:'$' dept:'依赖'} }
直接使用别名
有时候,在开发某些功能时,需要模拟服务器来展示功能时,这时候我们就需要用到本地服务器来模拟。又或者在开发完成后,我们在发布网站之前都会在本地服务器上运行,测试一下网站的功能和效果的展现,测试完成后再上传到购买的主机空间正式上线使用。
那么,有什么软件或者什么插件之类的可以模拟本地服务器呢?接下来就介绍几款优秀的web本地服务器。
(以下环境基于MAC的OS X下,与Windows配置相差不大)
XAMPP
顾名思义 (Apache+MySQL+PHP+PERL)
XAMPP是利用Apache服务,能够模拟本地服务器可以取到PHP文件从而获取MySQL文件,就是说可以自己新建PHP后台文件和JSON数据文件,可以模拟一些像利用AJAX请求,向后台拿到数据,完成一个完整的请求。
XAMPP默认的根目录是/Applications/XAMPP/xamppfiles/htdocs,把文件夹(yourProject)拖到htdocs,在浏览器输入http://localhost/yourProject,但是这样相当麻烦,这就需要配置根目录了。
在XAMPP软件界面点击Manage Servers → Configure → Open Conf File 点击 YES 进入 httpd.conf文件,
command+F 搜索 “docs”,找到 DocumentRoot 和 Directory
改成自己想要的目录就可以了。
我的文件夹为/Users/liangyongxin/desktop/mydemo
还有配置主机和站点这里就不多说了。各位可以百度一下。
一款基于Node.js的命令行http服务器,利用node.js开启本地服务,下载前请先自行下载node服务。
node地址:https://github.com/nodejs/node
安装方式:
npm install http-server -g
启动方法,直接在所在项目文件夹下开启服务:
http-server -open
hs -o //简写也可以
http-server 地址:https://github.com/indexzero/http-server
一款可以让你省时的浏览器同步测试工具,开启服务后,pc端、手机端同步更新,快速查看测试效果。而且是完全免费的。
官方中文网:http://www.browsersync.cn/
github地址:https://github.com/BrowserSync/browser-sync
安装方式:
npm install -g browser-sync
启动方式,直接在所在项目文件夹下开启服务:
// --files "路径是相对于运行该命令的项目(目录)"
browser-sync start --server --files "dist"
// 监听css文件
browser-sync start --server --files "css/*.css"
// 监听css和html文件
browser-sync start --server --files "css/*.css, *.html"
具体监听可查看官网
,有详细例子解释。一般监听整个项目文件夹。
开启本地服务后,系统会自动生成一个本地地址和一个外网地址
此时可以使用手机打开外网地址就可查看(可能需要同一wifi下)。
一般来说,使用以上几个本地服务器就足够了。
(转自)
阅读原文《分享一些前端开发中最常用的JS代码片段》
//匹配字母、数字、中文字符
/^([A-Za-z0-9]|[\u4e00-\u9fa5])*$/
//验证邮箱
/^\w+@([0-9a-zA-Z]+[.])+[a-z]{2,4}$/
//验证手机号
/^1[3|5|8|7]\d{9}$/
//验证URL
/^http:\/\/.+\./
//验证身份证号码
/(^\d{15}$)|(^\d{17}([0-9]|X|x)$)/
//匹配中文字符的正则表达式
/[\u4e00-\u9fa5]/
//匹配双字节字符(包括汉字在内)
/[^\x00-\xff]/
// 原生js
document.getElementById('btn').addEventListener('click', function (event) {
event = event || window.event;
if (event.stopPropagation){
// w3c方法 阻止冒泡
event.stopPropagation();
} else{
// ie 阻止冒泡
event.cancelBubble = true;
}
}, false);
// jQuery
$('#btn').on('click', function (event) {
event.stopPropagation();
});
原生js
document.getElementById('btn').addEventListener('click', function (event) {
event = event || window.event;
if (event.preventDefault){
// w3c方法 阻止默认行为
event.preventDefault();
} else{
// ie 阻止默认行为
event.returnValue = false;
}
}, false);
jQuery
// jQuery
$('#btn').on('click', function (event) {
event.preventDefault();
});
$('#content').on("mousewheel DOMMouseScroll", function (event) {
// chrome & ie || // firefox
var delta = (event.originalEvent.wheelDelta && (event.originalEvent.wheelDelta > 0 ? 1 : -1)) ||
(event.originalEvent.detail && (event.originalEvent.detail > 0 ? -1 : 1));
if (delta > 0) {
// 向上滚动
console.log('mousewheel top');
} else if (delta < 0) {
// 向下滚动
console.log('mousewheel bottom');
}
});
function isSupportSVG() {
var SVG_NS = 'http://www.w3.org/2000/svg';
return !!document.createElementNS &&!!document.createElementNS(SVG_NS, 'svg').createSVGRect;
}
// 测试
console.log(isSupportSVG());
function isSupportCanvas() {
if(document.createElement('canvas').getContext){
return true;
}else{
return false;
}
}
// 测试,打开谷歌浏览器控制台查看结果
console.log(isSupportCanvas());
function isWeiXinClient() {
var ua = navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i)=="micromessenger") {
return true;
} else {
return false;
}
}
// 测试
alert(isWeiXinClient());
$('#myImage').click(function(event){
//获取鼠标在图片上的坐标
console.log('X:' + event.offsetX+'\n Y:' + event.offsetY);
//获取元素相对于页面的坐标
console.log('X:'+$(this).offset().left+'\n Y:'+$(this).offset().top);
});
<!-- dom -->
<input id="send" type="button" value="发送验证码">
原生js版本
// 原生js版本
var times = 60, // 临时设为60秒
timer = null;
document.getElementById('send').onclick = function () {
// 计时开始
timer = setInterval(function () {
times--;
if (times <= 0) {
send.value = '发送验证码';
clearInterval(timer);
send.disabled = false;
times = 60;
} else {
send.value = times + '秒后重试';
send.disabled = true;
}
}, 1000);
}
jQuery版本
// jQuery版本
var times = 60,
timer = null;
$('#send').on('click', function () {
var $this = $(this);
// 计时开始
timer = setInterval(function () {
times--;
if (times <= 0) {
$this.val('发送验证码');
clearInterval(timer);
$this.attr('disabled', false);
times = 60;
} else {
$this.val(times + '秒后重试');
$this.attr('disabled', true);
}
}, 1000);
});
var browser = {
versions: function() {
var u = navigator.userAgent;
return {
trident: u.indexOf('Trident') > -1, //IE内核
presto: u.indexOf('Presto') > -1, //opera内核
webKit: u.indexOf('AppleWebKit') > -1, //苹果、谷歌内核
gecko: u.indexOf('Firefox') > -1, //火狐内核Gecko
mobile: !!u.match(/AppleWebKit.*Mobile.*/), //是否为移动终端
ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios
android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, // android
iPhone: u.indexOf('iPhone') > -1 , //iPhone
iPad: u.indexOf('iPad') > -1, //iPad
webApp: u.indexOf('Safari') > -1 //Safari
};
}
}
if (browser.versions.mobile() || browser.versions.ios() || browser.versions.android() || browser.versions.iPhone() || browser.versions.iPad()) {
alert('移动端');
}
function fullscreen(element) {
if (element.requestFullscreen) {
element.requestFullscreen();
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if (element.webkitRequestFullscreen) {
element.webkitRequestFullscreen();
} else if (element.msRequestFullscreen) {
element.msRequestFullscreen();
}
}
fullscreen(document.documentElement);
(说明:本文原载2016年第24期《财新周刊》)
我在杭州工作,周末通常去爬山。今年九月,这里将举办盛大的G20峰会。全城都在忙碌地筹备,山路上也不例外。距离西湖最近的一圈山头,都在安装照明设备,准备在夜间亮灯。
那些灯柱都是铸铁做的,高度六七米,非常沉重。施工队使用骡子,将灯柱从山脚运到峰顶。
我在山路上遇过好几次驮运设备的骡子。它们背上两边各绑着一根极重的灯柱,默默地低着头,蹒跚地踩在石阶上。等爬到峰顶,卸下设备以后,又返回山脚,驮运下一批。每头骡子的屁股后面,都跟着一个拿着木棍、看管它的施工人员,防止它走错路。
有一次,我看见一头骡子缓缓走着,突然停下来,低着头毫无表情地一动不动,不知道是累了还是不想走了。监工见状,立即拿棍子戳它,它茫然地抬起头,又顺从地继续向前走了。
看到这一幕,我非常感慨。骡子并不知道,为何要把如此重的铁管背到山顶,就是因为主人要求它这么做,就任劳任怨地干了。哪怕有那么一瞬间,它的内心有过一丝抗拒或疑问,主人一施压,它就不再追问了,回到正常的状态,默默地听任摆布。
我从这头骡子身上,想到很多人不也是这样,背负重压,被推着前行,却不知为何。他们埋头勤奋工作,努力完成上级交付的每一个任务,别人让你干什么就干什么,却没有思考过这一切到底为了什么。
说起来,中国人与骡子真的有很多相似性。一方面,许多人背上的生活压力,不会比那头骡子小多少,尤其是底层民众。另一方面,中国人的勤劳和忍耐能力,更是有过之而无不及。最重要的一点是,骡子只能接受现实,接受命运的安排,人又何尝不是如此呢?
不过,骡子是确实没有办法,它不会思考,没有能力抗拒命运的安排。人可以思考,也有行动能力。我感叹的是,那么多人心甘情愿地放弃,这种只有人类才具有的天赋,"自愿"像骡子那样活着,还说"这就是命,能有什么办法呢",或者"我也不知道啊,除了这个,我还能干什么"。
读到这里,你也许会说,”哪有你说的那么严重,工作就是为了赚钱。什么接受命运的摆布、放弃思考能力。为了多赚一点钱努力工作,不是很合理吗,跟骡子扯得上关系吗?”
当然,在生存面前,一切都是合理的。骡子为了生存,必须俯首听命。但是,21世纪的中国青年,生存本身似乎已经不是问题了。在这样一个产能和资本过剩的时代,除了赚钱以外,是不是应该对自己的人生做一些认真的思考,不要让”赚钱”成为思想懒惰的借口。退一步说,就算你像骡子那样活着,真的赚到了很多钱,是否可以就此认定,当一头骡子是正确的事情?
说实话,我不太确定。假如有一道填空题,”如果因此可以获得彩票头奖,为什么不__呢?”,在下划线的地方填入”当一头骡子”,似乎逻辑上也说得过去。但从内心里,或者说基于我的偏执,我还是认为这样是不对的。
让我举一个实际的例子。我比较熟悉”软件工程师”这个职业,也就是职业程序员。在我看来,这种职业跟骡子有很多相似性,尤其在大公司里。因为大公司有严格的分工,设计师出视觉稿,业务部门提出需求和业务逻辑,产品经理负责项目实施,工程师的职责就是严格按照设计稿,将产品一模一样地实现出来。本质上,这跟骡子背铁管上山,并没有区别。
《黑客与画家》的作者保罗•格雷厄姆,做过一个非常好的概括。
"......(你)只是一个负责实现领导意志的技术工人,职责就是根据规格说明书写出代码,其实与一个挖水沟的工人是一样的,从这头挖到那头,仅此而已,从事的都是机械性的工作。"
我不是说这样的流程有什么不对,而是说在这个流程里,人只是充当一种工具。就像骡子只是铁管上山的一种手段,你只是产出代码的一种手段,本身并没有”自由意志”体现在里面。或者说,你身上体现的都是他人的(或资本的)意志,你无法表现出自我。评价骡子的标准是,铁管背得比较多、比较快,评价软件工程师的标准又何尝不是如此呢,都是看是否忠实有效地实现那些外部意志。
我见过许多年轻的程序员勤奋工作,从早到晚一刻不停地编码,周末也来加班,努力完成公司的一个个目标,从来不问、甚至不想”这种需求对不对”、”这个功能有没有必要”,更不要说想一想”我的人生规划是什么”。中国的现实也很残酷,公司的哲学就是告诉你做什么,你就做什么,不想做就离开。
我可以想象,等到九月盛会召开时,工程完成,山头亮起灯光,与明月共同照映山脚下的西湖,平湖如镜,游人泛舟,夏夜凉风吹拂,何等的美景美事。骡子参与了这一切的创造过程,但是有谁会记得它们呢,它们的宿命就是接着去下一个工程背铁管。
骡子只是施工队的工具,跟锄头或者扁担没有本质区别。但你不是他人的工具,你活着不是为了被动地被他人使用,而是应该要有自己的价值。我觉得,人应该过一种有乐趣、有追求、自己做主的生活,而不能像骡子那样被推着走。
(完)
github (程序员学习源码必备): https://github.com/
Awesomes(统计当前流行热点技术):https://www.awesomes.cn/
前端乱炖: http://www.html-js.com/
NaN这个特殊的Number与所有其他值都不相等,包括它自己:
NaN === NaN; // false
唯一能判断NaN的方法是通过isNaN()函数:
isNaN(NaN); // true
1 / 3 == (1 - 2 / 3); // false
1 / 3 === (1 - 2 / 3); // false
Math.abs(1 / 3 - (1 - 2 / 3)) < 0.0000001; // true
关于最后两者,大多数情况下,我们都应该用null。undefined仅仅在判断函数参数是否传递的情况下有用。
需要特别注意的是,字符串是不可变的,如果对字符串的某个索引赋值,不会有任何错误,但是,也没有任何效果:
var s = 'Test';
s[0] = 'X';
alert(s); // s仍然为'Test'
JavaScript为字符串提供了一些常用方法,注意,调用这些方法本身不会改变原有字符串的内容,而是返回一个新字符串
。
总结:string有其不可变的原始值。
Array可以通过索引把对应的元素修改为新的值,因此,对Array的索引进行赋值会直接修改这个Array:
var arr = ['A', 'B', 'C'];
arr[1] = 99;
arr; // arr现在变为['A', 99, 'C']
总结:数组为object,对象中的值是可改变的。
数组直接量的语法允许有可选的结尾的逗号:
var arr1 = [1,2,3, ];
alert(arr1.length); // 3,而不是4;
变量、对象属性和数组元素均是左值。
ECMAScript规范允许内置函数返回一个左值,但自定义函数则不能返回左值。
运算结果是依赖于运算符的运算顺序的,比如:
1 + true + "string"; → "2string";
1 + (true + "string"); → "1truestring"
var obj = { a:1 };
var p = null;
o && obj.a; // 1: obj 是真值,因此返回值为 obj.a ;
p && p.a; // null: p 是假值,因此将其返回,而并不去计算 p.a,所以没有报错;
例如:
if(a == b) stop(); //只有在a == b 的时候才调用 stop();
(a == b) && stop(); //同上;
通常喜欢使用逻辑或的短路运算给参数默认值
function getSum(a,b,c){
//通常喜欢使用逻辑或的短路运算给参数默认值
a = a || 0;
b = b || 0;
c = c || 0;
return a + b + c;
}
console.log(getSum(1,2,3));
console.log(getSum(1,2));
var d1 = new Date(2016,8,22); //2016,9,22
var d2 = new Date("2016,8,22"); //2016,8,22
var d3 = new Date("2016,10,15");
d3.getDate(); // 获取星期数 0~6
d3.getDay(); // 获取一个月中的天数
d3.date.getMonth(); //9 获取月份数,0-11,
vertical:middle;
可与图片居中对齐. display:none;
完全隐藏,在页面上不占据位置(完全消失)页面上两个div,一上一下,上面div1设置margin-bottom:200px; 下面div2设置margin-top:100px;则两个div 在垂直方向上的margin 为 200px;(谁大谁说话)
父盒子包着一个子盒子,子盒子设置margin-top:50px;则父盒子跟着子盒子一起掉下去;
解决方法:
如果大盒子里面有一个小盒子,小盒子没有设置宽度,那么将来小盒子内容的宽高默认跟大盒子一样,但是这个时候会给小盒子设置一个padding-left,padding-right,那么将来小盒子的大小不会改变,但是内容会变小
编写HTML代码时,换行、多个空格、tab等,在页面上只会显示一个空格
/line-height
font-family ;l
ink v
isited h
over(常用) a
ctive position 定位名 | static | relative | absolute | fixed |
---|---|---|---|---|
是否脱标 | 默认定位 | 是 | 是 | 是 |
是否覆盖在标上 | 否 | 是 | 是 | 是 |
是否改变显示方式 | 否 | 否 | 是,inline-block | 是,inline-block |
定位的位置(基点) | 否 | 自己的顶点 | 1.没有父盒子→body顶点 2.父盒子没定位→body顶点 3.父盒子有定位→父盒子顶点 | body顶点 |
应用:子绝父相
为了突出重要性,<h1><a>此处放对logo的描述</a></h1>
a标签设置 text-indent: -10000;(移出浏览器)
!important > 行内 > ID选择器 > 伪类选择器 > 类选择器 > 标签选择器 > 通用选择器 >继承
z-index: ;
定位 > 浮动 > 标准流
magin,和padding在行内元素的上下设置是不起作用的,但是左右不受影响