梁小新blog


  • Home

  • Archives

  • Tags
梁小新blog

解决图片验证码点击刷新问题

Posted on 2017-05-17

Question

1
2
// HTML
<img id="captchaImg" src="/member/getCaptcha" alt="" width="100px" class="captcha-img">

在日常开发中,常常需要用到图片验证码,点击验证码需要更换图片验证码,但因为浏览器会有缓存机制,从后台接口/member/getCaptcha的图片因为src属性不变所以再次点击触发不会更新,那么如何实现点击再次从后台获取?

Answer

思路:src路径唯一,点击触发不会更新,那么可利用地址后?接参数随机实现

实现:在后台接口地址 + 随机数 即可实现点击更换图片验证码

1
2
3
4
5
6
7
8
9
// HTML
<img id="captchaImg" src="/member/getCaptcha" alt="" width="100px" class="captcha-img">
// JS
// 点击触发换验证码
$('.captcha-img').on('click',function () {
// 在图片后面加上随机数换图片
var ran = Math.random();
$(this).attr('src','/member/getCaptcha?'+ran)
});
梁小新blog

vue2.0嵌套路由实现豆瓣电影分页功能

Posted on 2017-01-12

前言

最近练习Vue,看到官方文档中的嵌套路由,
不做不知道,实在是太坑了,网上资料demo少之又少,然后自己就做了一个demo,用了vue2.0嵌套路由实现豆瓣电影分页功能,供大家学习学习,写得不好望见谅。

官方文档给出的demo:http://jsfiddle.net/yyx990803/L7hscd8h/

Demo简单介绍

主路由: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:
one

分页2:
two

分页3:
three

跳到正在热映:
hot

demo地址:https://github.com/liangxiaoxin/doubandemo

数据来自豆瓣电影API。

代码写得好烂,凑合着看吧,反正子路由还是成功的啊!哈哈哈

梁小新blog

利用n管理node版本,轻松切换node

Posted on 2017-01-10

前言

这段时间,一直都是用node的稳定版本,最近因为工作需要,需要用到其他node版本,Google搜了一下,有很好的一个解决方案,选择node版本管理工具,轻松切换node。有两个很好的node版本工具, nvm 和 n ,那么问题来了,选择哪一个呢?

废话,当然是哪个好用就用哪个嘛!

虽然热度 nvm 比 n 高一点,无意中看到FED写的一篇blog《管理 node 版本,选择 nvm 还是 n?》,觉得 n 比较简单易用,然后就毫不犹豫地选择了 n,全局安装之后输入命令就可以无缝切换了。

n

n github地址: https://github.com/tj/n

nvm github地址:https://github.com/creationix/nvm

安装

$ npm install -g n

下载完成后就可以使用 n 了。

利用 n 下载所需node

$ 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
梁小新blog

seajs和requirejs实现模块化开发

Posted on 2017-01-07

seajs模块化加载框架


5分钟入门

  • 1: 引包
  • 2: 启动 seajs.use("../static/lucky/src/main"); main.js可以省略后缀
    • 建议: seajs.use([]); 第一:建议传数组,第二:不管使用什么的时候,尽量省略.js
  • 3: 不管是谁,首先你得自己是一个模块,然后还可以向模块导出数据
    • define(函数或者数组);
    • 建议掌握传递函数的方式,module.exports 可以用return 来替代
  • 4: 你本身是一个模块,你可以引入模块,拿到返回值require('./data');
    • 如果不需要返回值。也可以require();
  • 5: 如果需要返回值,也可以通过module.exports = xxxx来让外部获取
    • exports用来挂载属性,module.exports是通用

sea.js官网:http://seajs.org/docs/

define

  • define如果不传function 那么传入的参数就是其返回值
  • 可以传入的数据有:
    • 对象、数组、字符串、function
  • define(function(require,exports,module){});

require

  • require的参数只能是字符串
  • require函数是我自己来实现,同样有没有必要加载多次
    • seajs中,加载第一次,就会放入到缓存中,接下来不需要读取文件
    • 缓存:指的就是当前模块执行后最终的module.exports,把其值保存起来
    • 多次获取module.exports的值只会有一个
  • 异步的调用方式
    • require.async(模块)

use的使用

  • seajs.use(数组,回调函数)
    • 回调函数的参数就是数组每个模块的返回值
    • 模块加载的顺序,和回调函数参数的顺序一定要一致
  • use函数是异步的

高级配置(难点,了解)

seajs.config({
    base: "../sea-modules/", //基础目录
    alias: {  //设置别名
      "jquery": "jquery/jquery/1.10.1/jquery.js",
      "jquery-easing": "jquery/easing/1.3.0/easing.js"
    }
});
  • base:属性是顶级目录,也可以理解为基础目录
    • 使用的方式,排除绝对路径和相对路径,直接写接下来的文件夹或者文件名,就ok
  • 应用场景:
    • 1: 配置是一个大家都使用的目录,只要该目录发生改变,修改base值,其他的引用也会改变
    • 2: 使用相对路径使用,逐个修改太麻烦,base路径修改,做跨盘符更方便
    • 3: 解决目录层级过深的问题
  • base目录默认是seajs的目录

几个属性的强调

  • base、alias、paths :使用只能是以非绝对路径和相对路径,既: 直接写名称 seajs.use('a')
  • 如果是seajs.use('x'); 优先匹配alias 和 paths,匹配上了不匹配base
  • alias和paths都能使用base
  • 在seajs中叫paths 只能匹配文件夹,使用需要拼接
  • 在requirejs中叫paths 可以是文件
  • requirejs: base = baseUrl,alias = paths

requireJS基本使用


  • 配置shim :垫片

    • 1:配置一个别名,该别名指向具体的文件
    • 2:将该别名进行垫的操作,告诉requirejs,我们需要的是文件中的哪一个对象

      shim:{ 'jquery':{exports:'$'},[垫其他对象] }
      

    其他配置与seajs差不多

    require官方网站:http://requirejs.org/

    requirejs官方中文网:http://www.requirejs.cn/

总结:seajs 与 requirejs


基本步骤

  • seajs
    • 步骤:1:引包、2:启动并指定入口模块、3:定义模块、4:引入模块、5:导出模块
      • 1:<script src> 2:seajs.use([xxx],回调) 3:define(function(require,exports,module){}) 4:var xxx = require(xxx) 5:module.exports = xxx
      • exports用来挂载属性简写,可以return
  • requirejs
    • 步骤:1:引包、2:启动并指定入口模块、3:定义模块、4:引入模块、5:导出模块
      • 1:.. 2:requirejs([],回调) 3: define(id,[依赖],回调(参数)) 5:return
  • requirejs也可以按照cmd的方式

    define(function(require,exports,module){})
    
  • 第三方的问题

    • seajs中:找到对应文件处理amd的地方,模拟处理cmd
      • if(define typeof === 'function' && define.cmd){ define(function(){return 对象})}
    • requirejs:
      • 设置paths:{jquery:'路径'}
      • 垫片 shim:{'jquery':{exports:'$' dept:'依赖'} }
      • 使用 直接使用别名
      • 在使用前端模块化框架的时候,为了少踩坑,可以考虑2点:
        • 启动的时候能给数组给数组
        • 能不给.js就不给.js

区别

  • AMD: async module define 异步模块定义
  • CMD: common module define 同步模块定义(CMD规范是玉伯出的)
  • 都可以进行异步加载 require.async
  • 从代码的角度来看:
    • seajs 是加载滞后(什么时候用,什么时候加载)
      • 懒加载
    • requirejs 是加载前置(需要用到什么,提前加载)
      • 预加载
  • 从官方加载机制的区别来看:
    • seajs 懒加载
    • require 提前加载
  • 从案例的加载机制来说:
    • seajs是随需要的时候加载
    • requirejs 会优先检查需要依赖,然后先加载依赖
梁小新blog

分享几款web本地服务器及搭建

Posted on 2016-11-22

有时候,在开发某些功能时,需要模拟服务器来展示功能时,这时候我们就需要用到本地服务器来模拟。又或者在开发完成后,我们在发布网站之前都会在本地服务器上运行,测试一下网站的功能和效果的展现,测试完成后再上传到购买的主机空间正式上线使用。

那么,有什么软件或者什么插件之类的可以模拟本地服务器呢?接下来就介绍几款优秀的web本地服务器。
(以下环境基于MAC的OS X下,与Windows配置相差不大)

XAMPP / WAMPP

XAMPP 顾名思义 (Apache+MySQL+PHP+PERL)

XAMPP是利用Apache服务,能够模拟本地服务器可以取到PHP文件从而获取MySQL文件,就是说可以自己新建PHP后台文件和JSON数据文件,可以模拟一些像利用AJAX请求,向后台拿到数据,完成一个完整的请求。

下载地址:https://www.apachefriends.org/download.html

XAMPP

下载完成后可以看到以下的界面,点击star,在浏览器输入 http://localhost/ 就能看到首页了。

XAMPP默认的根目录是/Applications/XAMPP/xamppfiles/htdocs,把文件夹(yourProject)拖到htdocs,在浏览器输入http://localhost/yourProject,但是这样相当麻烦,这就需要配置根目录了。

配置XAMPP根目录

在XAMPP软件界面点击Manage Servers → Configure → Open Conf File 点击 YES 进入 httpd.conf文件,
command+F 搜索 “docs”,找到 DocumentRoot 和 Directory

XAMPP1

改成自己想要的目录就可以了。

我的文件夹为/Users/liangyongxin/desktop/mydemo

还有配置主机和站点这里就不多说了。各位可以百度一下。

http-server

一款基于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

browser-sync

一款可以让你省时的浏览器同步测试工具,开启服务后,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下)。

一般来说,使用以上几个本地服务器就足够了。
​

梁小新blog

分享一些前端开发中常用的JS代码片段

Posted on 2016-10-26

(转自) 阅读原文《分享一些前端开发中最常用的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');
    } 
});

检测浏览器是否支持svg

function isSupportSVG() { 
    var SVG_NS = 'http://www.w3.org/2000/svg';
    return !!document.createElementNS &&!!document.createElementNS(SVG_NS, 'svg').createSVGRect; 
} 

// 测试
console.log(isSupportSVG());

检测浏览器是否支持canvas

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());

jQuery 获取鼠标在图片上的坐标

$('#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);
});

js判断是否移动端及浏览器内核

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('移动端'); 
}

HTML5全屏

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);
梁小新blog

你的命运不是一头骡子

Posted on 2016-09-29

(说明:本文原载2016年第24期《财新周刊》)

我在杭州工作,周末通常去爬山。今年九月,这里将举办盛大的G20峰会。全城都在忙碌地筹备,山路上也不例外。距离西湖最近的一圈山头,都在安装照明设备,准备在夜间亮灯。

工人在准备灯

那些灯柱都是铸铁做的,高度六七米,非常沉重。施工队使用骡子,将灯柱从山脚运到峰顶。

我在山路上遇过好几次驮运设备的骡子。它们背上两边各绑着一根极重的灯柱,默默地低着头,蹒跚地踩在石阶上。等爬到峰顶,卸下设备以后,又返回山脚,驮运下一批。每头骡子的屁股后面,都跟着一个拿着木棍、看管它的施工人员,防止它走错路。

有一次,我看见一头骡子缓缓走着,突然停下来,低着头毫无表情地一动不动,不知道是累了还是不想走了。监工见状,立即拿棍子戳它,它茫然地抬起头,又顺从地继续向前走了。

看到这一幕,我非常感慨。骡子并不知道,为何要把如此重的铁管背到山顶,就是因为主人要求它这么做,就任劳任怨地干了。哪怕有那么一瞬间,它的内心有过一丝抗拒或疑问,主人一施压,它就不再追问了,回到正常的状态,默默地听任摆布。

伤心的骡子

我从这头骡子身上,想到很多人不也是这样,背负重压,被推着前行,却不知为何。他们埋头勤奋工作,努力完成上级交付的每一个任务,别人让你干什么就干什么,却没有思考过这一切到底为了什么。

说起来,中国人与骡子真的有很多相似性。一方面,许多人背上的生活压力,不会比那头骡子小多少,尤其是底层民众。另一方面,中国人的勤劳和忍耐能力,更是有过之而无不及。最重要的一点是,骡子只能接受现实,接受命运的安排,人又何尝不是如此呢?

不过,骡子是确实没有办法,它不会思考,没有能力抗拒命运的安排。人可以思考,也有行动能力。我感叹的是,那么多人心甘情愿地放弃,这种只有人类才具有的天赋,"自愿"像骡子那样活着,还说"这就是命,能有什么办法呢",或者"我也不知道啊,除了这个,我还能干什么"。

一个人独自前行

读到这里,你也许会说,”哪有你说的那么严重,工作就是为了赚钱。什么接受命运的摆布、放弃思考能力。为了多赚一点钱努力工作,不是很合理吗,跟骡子扯得上关系吗?”

当然,在生存面前,一切都是合理的。骡子为了生存,必须俯首听命。但是,21世纪的中国青年,生存本身似乎已经不是问题了。在这样一个产能和资本过剩的时代,除了赚钱以外,是不是应该对自己的人生做一些认真的思考,不要让”赚钱”成为思想懒惰的借口。退一步说,就算你像骡子那样活着,真的赚到了很多钱,是否可以就此认定,当一头骡子是正确的事情?

说实话,我不太确定。假如有一道填空题,”如果因此可以获得彩票头奖,为什么不__呢?”,在下划线的地方填入”当一头骡子”,似乎逻辑上也说得过去。但从内心里,或者说基于我的偏执,我还是认为这样是不对的。

让我举一个实际的例子。我比较熟悉”软件工程师”这个职业,也就是职业程序员。在我看来,这种职业跟骡子有很多相似性,尤其在大公司里。因为大公司有严格的分工,设计师出视觉稿,业务部门提出需求和业务逻辑,产品经理负责项目实施,工程师的职责就是严格按照设计稿,将产品一模一样地实现出来。本质上,这跟骡子背铁管上山,并没有区别。

《黑客与画家》的作者保罗•格雷厄姆,做过一个非常好的概括。

"......(你)只是一个负责实现领导意志的技术工人,职责就是根据规格说明书写出代码,其实与一个挖水沟的工人是一样的,从这头挖到那头,仅此而已,从事的都是机械性的工作。" 

我不是说这样的流程有什么不对,而是说在这个流程里,人只是充当一种工具。就像骡子只是铁管上山的一种手段,你只是产出代码的一种手段,本身并没有”自由意志”体现在里面。或者说,你身上体现的都是他人的(或资本的)意志,你无法表现出自我。评价骡子的标准是,铁管背得比较多、比较快,评价软件工程师的标准又何尝不是如此呢,都是看是否忠实有效地实现那些外部意志。

我见过许多年轻的程序员勤奋工作,从早到晚一刻不停地编码,周末也来加班,努力完成公司的一个个目标,从来不问、甚至不想”这种需求对不对”、”这个功能有没有必要”,更不要说想一想”我的人生规划是什么”。中国的现实也很残酷,公司的哲学就是告诉你做什么,你就做什么,不想做就离开。

山

我可以想象,等到九月盛会召开时,工程完成,山头亮起灯光,与明月共同照映山脚下的西湖,平湖如镜,游人泛舟,夏夜凉风吹拂,何等的美景美事。骡子参与了这一切的创造过程,但是有谁会记得它们呢,它们的宿命就是接着去下一个工程背铁管。

骡子只是施工队的工具,跟锄头或者扁担没有本质区别。但你不是他人的工具,你活着不是为了被动地被他人使用,而是应该要有自己的价值。我觉得,人应该过一种有乐趣、有追求、自己做主的生活,而不能像骡子那样被推着走。

(完)

梁小新blog

收集优秀前端网站and博客

Posted on 2016-09-27

前端学习论坛网站

  • github (程序员学习源码必备): https://github.com/

  • Awesomes(统计当前流行热点技术):https://www.awesomes.cn/

  • 前端乱炖: http://www.html-js.com/

  • 前端网: www.qdfuns.com

前端牛人blog

  • 阮一峰: http://www.ruanyifeng.com/blog/ (个人比较喜欢)
  • 廖雪峰的官方网站 http://www.liaoxuefeng.com/
  • Aaron个人技术博客 http://www.haorooms.com/

前端学习团队blog

  • 大搜车前端团队博客 http://f2e.souche.com/blog/
  • 淘宝前端团队(FED) http://taobaofed.org/

hexo + github 建立个人博客教程

  • http://www.jianshu.com/p/465830080ea9

前端插件

  • wiper中文网 http://www.swiper.com.cn/ (一款免费的轮播图插件)
梁小新blog

Javascript中注意之处

Posted on 2016-09-25

记录一些学习Javasrcipt中要注意的地方

关于NAN

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

关于空

  • 0是一个数值;
  • ‘’表示长度为0的字符串;
  • null表示“空”;
  • undefined表示值未定义。

关于最后两者,大多数情况下,我们都应该用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"

&& and || 短路现象

&& 逻辑与运算
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)); 

Date 日期对象

日期的声明
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,
梁小新blog

HTML+CSS重点总结

Posted on 2016-09-13

元素的分类

  • 行内元素( inline ):a b strong del em ins span
  • 行内块级元素( inline-block ):input button img textarea
  • 块级元素( block ):div ul li dl dd dt ol

标签的语义化理解

  • (关键)合适的地方使用合适的标签
  • 对SEO的好处(讨好网络爬虫)
  • 提升用户体验
  • 方便代码的维护和修改

SEO

  • 页面的语义化
  • meta和title标签的对页面的描述
  • 广发外链
  • 将动态页面静态化(有助于网络爬虫)

各种居中

1.水平居中
  • 行内元素:父元素设置 text-align:center;(注意:不能直接在行内元素上设置,没效果)
  • 行内块级元素:父元素设置 text-align:center;
  • 块级元素:该元素上设置 margin:0 auto;
  • 绝对定位元素在父盒子上水平居中:left:50%(父盒子宽度的一半);margin-left:负的子盒子宽度的一半;
2.垂直居中
  • inline: 父元素上设置 line-height:父元素高度 ;(可直接在inline元素上设置该属性)
  • inline-block:1.在该元素设置 position:relative; top:父元素高度的一半; 2.margin-top:负的该元素高度的一半;
  • block: 1.在该元素设置 position:relative; top:父元素高度的一半; 2.margin-top:负的该元素高度的一半;(理解:先移离中间的下一点,再上来一点点,居中,OK)
  • 左边图片,右边文字(此时图片与文字的基线对齐):文字设置vertical:middle;可与图片居中对齐.

各种隐藏

  • overflow:hidden; 把在容器超出的部分隐藏掉;
  • visibility:hidden; 可视化隐藏,在页面上会保留原来的位置(隐身の术,但在页面上占据位置)
  • display:none; 完全隐藏,在页面上不占据位置(完全消失)

特殊现象

1.margin的合并现象
页面上两个div,一上一下,上面div1设置margin-bottom:200px; 下面div2设置margin-top:100px;则两个div 在垂直方向上的margin 为 200px;(谁大谁说话) 
2.margin的塌陷现象
父盒子包着一个子盒子,子盒子设置margin-top:50px;则父盒子跟着子盒子一起掉下去; 

解决方法:

  1. 给父盒子添加一个上边框(边框)
  2. 父盒子设置 overflow:hidden;
  3. 浮动也可以
3.padding特殊现象
如果大盒子里面有一个小盒子,小盒子没有设置宽度,那么将来小盒子内容的宽高默认跟大盒子一样,但是这个时候会给小盒子设置一个padding-left,padding-right,那么将来小盒子的大小不会改变,但是内容会变小
4.空格合并现象
编写HTML代码时,换行、多个空格、tab等,在页面上只会显示一个空格

属性的连写规则

  • font: font-style font-weight font-size/line-height font-family ;
  • background: background-color background-image background-repeat background-position ;
  • margin:10px 5px; 上下10px 左右5px
  • margin :10px 5px 7px; 上10px 左右5px 下7px
  • margin:5px 3px 4px 9px; 上 右 下 左(顺时针trbl)

继承

  • text- line- font- 系列开头属性都可以继承
  • color 可继承
  • a标签颜色不能继承(浏览器有默认设置)
  • h系列大小不能继承(浏览器有默认设置)
  • 盒子 width height 不能叫继承 (no)

伪类

  • a 链接 : link visited hover(常用) active
  • :focus :input type=text 获取焦点时 a链接也可用
  • :first-child : 选择器 h3:first-child →匹配同辈的所有元素中,第一个元素并且是 h3 的元素。
  • :after 给元素的后面添加内容 (常用于伪类浮动)

CSS选择器的种类

  • !important:
  • 行内: 不用
  • ID选择器: 唯一性 #ID{}
  • 类选择器: 可多个,可重复使用 .className {}
  • 伪类选择器: 满足特定条件,完成某个动作 :hover{}
  • 标签选择器: p{} div{} span{}
  • 通用选择器 *{ } 用于CSS初始化
  • 继承
  • 并集选择器
  • 后代选择器 .sss p → .sss 下面的所有元素p → 孙子代也会选中
  • 子代选择器 .sss>p → .sss下面的所有子元素p → 孙子代没有选中

定位的比较

position 定位名 static relative absolute fixed
是否脱标 默认定位 是 是 是
是否覆盖在标上 否 是 是 是
是否改变显示方式 否 否 是,inline-block 是,inline-block
定位的位置(基点) 否 自己的顶点 1.没有父盒子→body顶点 2.父盒子没定位→body顶点 3.父盒子有定位→父盒子顶点 body顶点

应用:子绝父相

css初始化

  • *{ padding: 0;margin :0; }
  • input button { borader: 0; }
  • 浮动 .fl{ float: left; } .fr{ float: right; }
  • 清除浮动 .clearfix{content: “”; height: 0; line-hehight: 0; display: block; visibility: hidden; clear: both;}
  • 布局时,看看页面大概有哪些公用样式

logo的处理

为了突出重要性,<h1><a>此处放对logo的描述</a></h1> 
a标签设置 text-indent: -10000;(移出浏览器)  

浮动的那些事

浮动的特点
  • float:left; float:right;
  • 脱离标准流,在页面上不占据位置;
  • 会改变元素的显示方式 inline-block;
  • 覆盖在标准流之上;
浮动注意点
  • 左右浮动的元素互不干扰
  • 浮动过后的元素没有空格
  • 文本会给浮动以后的元素“让位” (应用:文字环绕)
浮动的位置
  • 如果元素A浮动,它的上一个元素B没有浮动,那么将来A会显示在B的下方
  • 如果元素A浮动它的上一个元素B也浮动,那么将来A会显示在B的后边(屏幕的宽度足够同时显示两个元素)
清除浮动
  • 父盒子之间添加一个空的div .clearfix{clear:both;}(不推荐用,给页面添加了更多的标签)
  • 给父盒子设置 overflow:hidden;(不推荐用,缺点:会使页面中的某些区域显示不完整)
  • 给父盒子添加一个伪类元素,(最常用) .clearfix{content: “”; height: 0; line-hehight: 0; display: block; visibility: hidden; clear: both;} 兼容IE6 .clear{ zoom:1; }

优先级

css选择器优先级

!important > 行内 > ID选择器 > 伪类选择器 > 类选择器 > 标签选择器 > 通用选择器 >继承

层级优先级

z-index: ;

定位 > 浮动 > 标准流

magin,和padding在行内元素的上下设置是不起作用的,但是左右不受影响

123
liangxiaoxin

liangxiaoxin

22 posts
© 2018 liangxiaoxin
Powered by Hexo
Theme - NexT.Muse