2016-06-09 12:47:09    101    0    0

使用负 margin 形成三栏布局

  1. 三栏必须浮动.
  2. 包含三栏的父容器不能高度塌陷。
  3. 左右两栏为固定宽度,中间可以自适应。
  4. 左右两栏通过负边距实现左右分布。
  5. 内容栏必须出现在在最前面。

实现圣杯布局的步骤

  • 原理:利用浮动和边栏的负margin以及relative定位填充父元素padding出来的区域来实现布局效果。
  • 步骤:
    1. 父元素底部通过伪元素清除浮动。
    2. 主体元素与父元素等宽。
    3. 主体及边栏元素设置浮动。
    4. 父元素设置左右padding,值与边栏元素宽度相同。如果两栏布局,则可只设置左或右padding;如果是三栏布局,且两个边栏宽度不同时,需使左右padding各对应一个边栏的宽度。
    5. 为边栏设置负margin。如果边栏放到左边,则margin-left: -100%,如果放到右边,则margin-left值等于该边栏宽度的负值。
    6. 边栏定位设置为position: relative,放到左边的边栏,left值为该边栏宽度的负值;放到右边的边栏,left值为该边栏的宽度值。

双飞翼布局实现步骤

  • 原理:为中间可变宽度的元素增加一层wrap,并利用浮动和边栏的负margin填充wrapmargin出来的区域来实现布局效果。
  • 步骤:
    1. 父元素底部通过伪元素清除浮动。
    2. 为主体元素添加wrap类的子元素。
    3. 主体元素与父元素等宽。
    4. 主体及边栏元素设置浮动。
    5. wrap设置左右margin,值与边栏元素宽度相同。如果两栏布局,则可只设置左或右margin;如果是三栏布局,且两个边栏宽度不同时,需使左右margin各对应一个边栏的宽度。
    6. 为边栏设置负margin。如果边栏放到左边,则margin-left: -100%,如果放到右边,则margin-left值等于该边栏宽度的负值。
2016-06-09 12:33:10    98    0    0

css hack

  • 由于不同厂商的浏览器或某浏览器的不同版本(如IE6-IE11,Firefox/Safari/Opera/Chrome等),对CSS的支持、解析不一样,导致在不同浏览器的环境中呈现出不一致的页面展现效果。这时,我们为了获得统一的页面效果,就需要针对不同的浏览器或不同版本写特定的CSS样式,我们把这个针对不同的浏览器/不同版本写相应的CSS code的过程,叫做CSS hack
  • hack的书写有以下三种方式:

    1. 属性前缀法(即类内部Hack),例如 IE6能识别下划线_和星号*,IE7能识别星*,但不能识别下划线_;
    2. 选择器前缀法(即选择器Hack),例如 IE6能识别* .class{},IE7能识别*+ .class{}
    3. IE条件注释法(即HTML头部引用if IE)例如:
    1. <!--[if IE6]>
    2. <p>这段文字只在IE6浏览器显示</p>
    3. <![endif]-->
    4. <!--[if IE7]>
    5. <p>这段文字只在IE7浏览器显示</p>
    6. <![endif]-->

渐进增强和优雅降级

  • 兼容、多浏览器覆盖是一个历史遗留问题,是随着浏览器的发展和w3c标准的建立而产生的。在写code的时候要分清主次,即先抓住主要需求,针对主流浏览器去开发,然后才去解决兼容、多浏览器覆盖问题,先完成再完美;
  • 渐进增强和优雅降级表面看上去差不多,都是在关注不同浏览器下的不同体验,关键的区别是它们所侧重的内容,以及这种不同造成的工作流程的差异。
  • 渐进增强是一个追加功能的过程,侧重于内容本身,首先针对低版本浏览器构建页面,保证最基本的功能,然后再针对高版本浏览器来改进样式的表现、交互的体检等,提高用户体验度;
  • 优雅降级针对那些最高级、最完善的浏览器来设计网站,将那些被认为“过时”或有功能缺失的浏览器下的测试工作安排在开发周期的最后阶段,在这种设计范例指引下,旧版浏览器并非关注的焦点,因此除了修复较大的错误之外,其它的差异将被直接忽略。
2016-06-09 12:27:04    949    4    1
  • 构造函数模式
  1. function Obj(name){
  2. this.name=name;
  3. Obj.prototype.say=function(){
  4. console.log(this.name);
  5. }
  6. }
  7. var obj=new Obj("adam");
  8. obj.say();//adam
  • 混合模式
  1. function Prenson(type){
  2. this.type=type;
  3. Prenson.prototype.say=function(){
  4. console.log(this.type);
  5. }
  6. }
  7. function Male(sex){
  8. Prenson.call(this,"human");
  9. this.sex=sex;
  10. }
  11. function create(obj){
  12. function F(){};
  13. F.prototype=obj;
  14. return new F();
  15. }
  16. Male.prototype=create(Prenson.prototype);
  17. Male.prototype.constructor=Male;
  18. var male=new Male("male");
  19. male.say();//hunman
  • 模块模式
  1. var dog=(function(){
  2. var age=19;
  3. function eat(){
  4. console.log("dog is eating meat, which is "+age+".");
  5. }
  6. return{
  7. eat:eat
  8. }
  9. })()
  10. dog.eat();
  • 工厂模式
  1. function objFactory(sex){
  2. function Male(sex){
  3. this.sex=sex;
  4. this.name="Kevin";
  5. }
  6. function Female(sex){
  7. this.sex=sex;
  8. this.name="Daisy";
  9. }
  10. var result=undef
2016-06-09 12:24:47    125    1    0

前端模块化

  • 模块化主要解决是前端团队在协作的时候出现命名冲突,依赖包管理的问题,另外利用模块化有利于代码的维护,提高代码的复用率。

CMD、AMD、CommonJS 规范和应用

  • CommonJS是指服务器端模块的规范,该规范规定了如何在服务器端定义一个模块,和如何引入一个模块。
    主要应用在node.js的模块系统上。

    例如:

  1. //定义一模块
  2. //module.js
  3. module.exports=function(){
  4. //todo
  5. }
  6. //引入模块
  7. //main.js
  8. fun1=require("module");
  9. //这边的fun1就是定义在模块里的匿名函数
  • AMD规范是浏览器端的引入规范,由于浏览器端只能通过异步加载模块,所以需要回调函数来执行接下来的操作。主要应用在RequireJs、curl、Dojo、Nodules等。

    例如:

  1. //定义模块,引入模块
  2. define('alpha',['jQuery','exports','Dojo'],function ($,exports,dojo) {
  3. exports.funcName = function () {
  4. return exports.funcName();
  5. // or return require('exports"').funcName();
  6. }
  7. });
  • CMD规范即Common Module Definition,是一套在sea.js推广过程中形成的一种规范。所以主要应用在sea.js上。

    例如:

  1. //引入模块
  2. //math.js
  3. define(function(require, exports, module){
  4. //注意:这边的函数的三个参数值是固定的
  5. exports.add=function(a,b){
  6. return a+b;
  7. }
  8. });
  9. //使用模块
  10. //use.js
  11. define(function(require, exports, module){
  12. //注意:这边的函数的三个参数值是固定的
  13. var add=require("math").add;//这边cmd是用到哪个模块再去加载哪个模块,A
2016-06-08 13:50:01    165    0    0

$()创建对象的实现

  1. 首先我们来看一下需求

    • $(“div”)可以创建一个对象
    • 该对象可以调用所有jq的元素公用方法
    • 该对象的方法可以产生链式调用
  2. 思考过程

    • (div)是函数名,而$(“div”)是运行该函数,所以可以判断该函数返回值肯定是一个对象,该对象代表了jquery.
    • $(“div”)可以调用所有元素的公用方法,所以可以知道,元素的方法都是绑定在jq原型上的.
    • $(“div”)的方法可以链式调用,则说明每个方法返回值都是一个当前jquery对象。
  3. 模拟实现

    下面用jQ的尝试实现下.

    1. function jQ(selector,context){
    2. // return a jQ instance
    3. }
    4. jQ.prototype={
    5. constructor:jQ//修正构造函数
    6. };

    由于要求返回的对象可以使用公用方法,那我们直接返回原型吧。

    1. function jQ(selector,context){
    2. // return a jQ instance
    3. return jQ.prototype;
    4. }
    5. jQ.prototype={
    6. constructor:jQ//修正构造函数
    7. };

    这样我们返回的对象中就可以直接使用公用的方法了,但是问题来了,怎么保证可以传参数?而且返回的是原型指针,万一我修改了原型指针指向的对象,那不是所有jQ的公用方法都无法使用了,所以我们返回的值必须是new 出来的。

    那我们试试new jQ呢?

    1. function jQ(selector,context){
    2. // return a jQ instance
    3. return new jQ(selector,context);
    4. }
    5. jQ.prototype={
    6. constructor:jQ//修正构造函数
    7. };

    感觉很完美,又有new,又能使用公用方法,是不是就这样好了呢?来,跑一跑看一下,哎哟,死循环了~为什么,哎哟,原来递归了,还没有终止条件,所以我们不能使用jQ作为构造函数,需要另外找一个构造函数.

    所以最终版本思路是这样的,在原型上挂一个别的初始化函数,然后把参数给他,最后修改下他的原型修改成为jQ的原型。这样即保证了new,还保证了公用方法使用。

2016-06-08 13:49:59    130    0    0

Promise

  • 在JavaScript的世界中,所有代码都是单线程执行的。由于这个“缺陷”,导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行。但是有时候我们的一些代码需要在这些异步执行完之后再执行,完成异步之下的同步执行,于是就诞生了Promise对象。

  • 简单应用

  1. // 0.5秒后返回input*input的计算结果:
  2. function multiply(input) {
  3. return new Promise(function (resolve, reject) {
  4. log('calculating ' + input + ' x ' + input + '...');
  5. setTimeout(resolve, 500, input * input);
  6. });
  7. }
  8. // 0.5秒后返回input+input的计算结果:
  9. function add(input) {
  10. return new Promise(function (resolve, reject) {//注意这边的返回值又是一个Promise对象,可以链式调用
  11. log('calculating ' + input + ' + ' + input + '...');
  12. setTimeout(resolve, 500, input + input);
  13. });
  14. }
  15. var p = new Promise(function (resolve, reject) {//这边的resolve和rejec是两个标记,决定执行then还是catch中的参数。
  16. log('start new Promise...');
  17. resolve(123);
  18. });
  19. p.then(multiply)//把multiply函数替代resolve执行了,参数是resolve上的参数。
  20. .then(add)
  21. .then(multiply)
  22. .then(add)
  23. .then(function (result) {
  24. log('Got value: ' + result);
  25. });

Deferred

  • deferred对

2016-06-08 13:49:59    155    2    0

实现的效果动图如下

效果图

理清需求

拿到效果图的第一步,理清下需求~

  • 首先,元素有左右上下四个方向。这边的问题在我如何在一个元素上划分上下左右四个区域?

  • 然后,鼠标进入元素和离开元素会有触发一个事件,这个简单js就自带了监听事件。

  • 最后,最难的是如何判断鼠标进入的时候会落在我们划分好的上下左右四个区域?

思路

  • 首先我们先来划分下四个区域,一般划分的都如下图
    区域划分图
    图里面有四个三角形,每个三角形代表的是一个方向,所以问题简化为如何在一个矩形里,根据对角线划分区域。由于元素存在坐标系,也就是X、Y轴,所以问题再次抽象成,如何得到两条对角线的线性函数。(初高中数学问题。)

  • 最后的问题我们就要来搞定判断鼠标落点的问题,首先我们知道我们可以在元素的鼠标事件中通过event得到鼠标的pageX和pageY,再配合元素的offsetLeft和offsetTop就可以得到鼠标在元素中的坐标。综合一下就变成了,我有一个坐标,且我知道对角线的函数表达式,请问我如何知道我这个坐标是在函数的下面还是上面?

  • 当然也许描述的比较抽象,我们可以类比一个例子,我现在有一个坐标(2,1),有一个函数y=x,值域大于0(既y>0),定义域大于0(既x>0),求该坐标在y=x的函数下面还是上面?(是不是感觉到了线性规划得到最优解的味道,对,少年,没有错,就是这样。)这里我们只要把坐标中的x值代入函数,然后判断代入的结果是否大于坐标的y值,如果大于则在函数下面,小于则在函数上面,什么?你问等于怎么办?当然是在函数上面,该坐标即在上面又在下面,所谓薛定谔的坐标是也(当然是在函数上了)。

  • 然后我们是不是可以扩展下,如果存在多个函数,再加上逻辑判断经常用的交集,并集是不是又有新的思维出现了呢?好了,这边就不再扩展了,下面直接上实现代码吧。

实现代码

注意:该demo只是简单的demo,其中有很多可以优化的地方,比如组件化,变量优化,利用发布订阅模式,实现事件联动

  1. <!DOCTYPE html>
  2. <html lang="ch">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Document</title>
  6. <s
2016-06-08 13:49:57    131    0    0

E:first-child:任何元素的第一个子元素E.
E:first-of-type:匹配同类型中的第一个同级兄弟元素E
E:[attr="value"]属性选择器
B + E:任何元素B的下一个兄弟元素E
B ~ E :B元素后面的拥有共同父元素的兄弟元素E
css中的cursor属性,outline属性。
nth-of-type(),nth-child()

CSS的样式优先级
在属性后面使用 !important会覆盖页面内任何位置定义的元素样式

作为style属性写在元素标签上的内联样式

id选择器

类选择器

伪类选择器

属性选择器

标签选择器

通配符选择器

浏览器自定义

基础    2016-06-08 13:49:57    142    0    0

常用浏览器:IE,Firefox,Chrome等
浏览器内核(决定浏览器解析方式):
1. Trident内核代表产品Internet Explorer,又称其为IE内核。Trident(又称为MSHTML),是微软开发的一种排版引擎。使用Trident渲染引擎的浏览器包括:IE、傲游、世界之窗浏览器、Avant、腾讯TT、Netscape 8、NetCaptor、Sleipnir、GOSURF、GreenBrowser和KKman等。
2. Gecko内核代表作品Mozilla FirefoxGecko是一套开放源代码的、以C++编写的网页排版引擎。Gecko是最流行的排版引擎之一,仅次于Trident。使用它的最著名浏览器有Firefox、Netscape6至9。
3. WebKit内核代表作品Safari、Chromewebkit 是一个开源项目,包含了来自KDE项目和苹果公司的一些组件,主要用于Mac OS系统,它的特点在于源码结构清晰、渲染速度极快。缺点是对网页代码的兼容性不高,导致一些编写不标准的网页无法正常显示。主要代表作品有Safari和Google的浏览器Chrome。
4. Presto内核代表作品OperaPresto是由Opera Software开发的浏览器排版引擎,供Opera 7.0及以上使用。它取代了旧版Opera 4至6版本使用的Elektra排版引擎,包括加入动态功能,例如网页或其部分可随着DOM及Script语法的事件而重新排版。

本博客版权归 博主和饥人谷所有,转载需说明来源

基础    2016-06-08 13:49:57    141    0    0

vertical-align: middle;

该属性是我们经常用到的用来垂直居中的属性,要使得该属性有切实可行的效果,则必须设置display:table-cell;来使得vertical-align: middle;生效。
举例代码如下

  1. <!DOCTYPE html>
  2. <html lang="ch">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Document</title>
  6. <style type="text/css">
  7. .ct{
  8. display: table-cell;
  9. width: 500px;
  10. height: 500px;
  11. border:1px green solid;
  12. vertical-align: middle;
  13. }
  14. .inner{
  15. height: 100px;
  16. width: 100px;
  17. background-color: red;
  18. }
  19. </style>
  20. </head>
  21. <body>
  22. <div class="ct">
  23. <div class="inner">
  24. </div>
  25. </div>
  26. </body>
  27. </html>

box-sizing属性

box-sizing 属性允许您以特定的方式定义匹配某个区域的特定元素。
取值有两个,content-box(宽度和高度分别应用到元素的内容框。
在宽度和高度之外绘制元素的内边距和边框。)和border-box(为元素设定的宽度和高度决定了元素的边框盒。就是说,为元素指定的任何内边距和边框都将在已设定的宽度和高度内进行绘制。
通过从已设定的宽度和高度分别减去边框和内边距才能得到内容的宽度和高度。)。

怪异模式和标准模式

  • 如果在文档开始处没有发现文档类型声明,则所有浏览器都会默认开启混杂模式(怪异模式)。
    在怪异模式下,浏览器的表现形式会有不同,因此需要兼容不同的 hack技术