前端大本营

HTML5,CSS3,Responsive,资料站

首先现在比较流行的区别IE与其他浏览器的CSS写法,

条件判断式

这种方法旨在页面读取中使用相应的判断条件,让浏览器读取指定的CSS样式

<!--[if !IE]><!--> 除IE以外的浏览器都可识别 <!--<![endif]-->
<!--[if IE]> 所有的IE浏览器可识别 <![endif]-->
<!--[if IE 6]> 仅IE6可识别 <![endif]-->
<!--[if lt IE 6]> IE6以及IE6以下版本可识别 <![endif]-->
<!--[if gte IE 6]> IE6以及IE6以上版本可识别 <![endif]-->
<!--[if IE 7]> 仅IE7可识别 <![endif]-->
<!--[if lt IE 7]> IE7以及IE7以下版本可识别 <![endif]-->
<!--[if gte IE 7]> IE7以及IE7以上版本可识别 <![endif]-->
<!--[if IE 8]> 仅IE8可识别 <![endif]-->
<!--[if IE 9]> 仅IE9可识别 <![endif]-->
稍作说明 ! 表示否,除了
lt 表示小于
lte 表示小于等于
gt 表示大于
gte 表示大于等于
( ) 优先计算
& 表示和,并且
| 表示或者
加载CSS2
<!--[if lt IE 9]>
加载CSS1(可以把要重写的写在这里).
<![endif]-->
以上内容均为了解即可, 这里告诉大家一个更有效的CSS写法,可以直接在样式表内,判断是否为IE浏览器。
@media all and (-ms-high-contrast:none){
   *******
}
简单吧,再不用为一个IE浏览器,来回在页内追加判断代码了
Tags: ,
Posted in CSS最新技术 | IE区别于其他浏览器的CSS代码写法。不使用判断条件式已关闭评论

本文参考了 http://www.zhangxinxu.com/wordpress/2015/01/chrome-absolute-display-visibility-render-bug/

在chrome中的样式是一个div 里面有两个子元素,含有float,并且含有position: absolute属性,其他浏览器都正常,
但在Chrome下,来回改变浏览器尺寸的时候,会出现浮动内容重影,位置不对的情况。参考了上面得文章,发现原来chrome一直存在着这么一个bug,
上文中为渲染表现BUG,我们先这面叫,到了大家最关心的地方,如何Hack这个问题,只要在你浮动的子元素或父元素上添加以下CSS即可解决。

-webkit-transform: translateZ(0); /* 没错,靠的就是你!*/
Posted in 精彩内容 | Chrome absolute绝对定位的BUG,导致浮动内容重影,位置不对已关闭评论

虽然CSS3已经流行很久了,但是总有一部分人还在使用IE8的浏览器。
没有办法,作为一个负责人的前端人员,总是要求满足客户的需求, 如何才能叫IE8 实现rgba的效果呢?

在IE8实现背景透明的效果
div{
    filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#66000000,endColorstr=#66000000); 
    background: rgba(0, 0, 0, 0.4);
}
div:not(:target){
    filter: none;
}
代码说明

利用IE以前制作过渡效果的代码,我们可以将起始颜色,和结束颜色设置为相同, 这样就可以实现半透明状态。
startColorstr=#66000000 其中66为透明度, 后面的000000为16进制的颜色代码
透明度的设置可以参考以下表格

透明度 0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100%
00 1A 33 4D 66 80 99 B3 CC E6 FF

Tags: , ,
Posted in 本站原创 | 使用Hack,让IE8实现 rgba的效果已关闭评论
2017 08/02 周三

解密JavaScript闭包

为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习。
对于JavaScript新手来说,闭包(Closures)是一个很神奇的东西。这篇博客将通过一个非常浅显的代码示例来解释闭包。

计数器

我们的目标是实现一个计数器,它的效果如下:

increment();  // Number of events: 1
increment();  // Number of events: 2
increment();  // Number of events: 3

可知,每次执行increment()都会输出“Number of events: N”,且N每次都会加1。

这个计数器最直观的实现方式如下:

var counter = 0;
function increment() 
{
  counter = counter + 1;
  console.log("Number of events: " + counter);
}

多个计数器

以上的代码非常简单。但是,当我们需要第二个计数器时,就会遇到问题了。当然,我们可以实现两个重复的计数器:

var counter1 = 0;
function incrementCounter1() 
{
  counter1 = counter1 + 1;
  console.log("Number of events: " + counter1);
}
var counter2 = 0;
function incrementCounter2() 
{
  counter2 = counter2 + 1;
  console.log("Number of events: " + counter2);
}
incrementCounter1();  // Number of events: 1
incrementCounter2();  // Number of events: 1
incrementCounter1();  // Number of events: 2

显然,以上的代码非常冗余,有待优化。当我们需要更多计数器时,使用这种方法将不太现实。这时,就需要神奇的闭包了。

使用闭包实现计数器

需要多个计数器,同时希望去除冗余代码的话,就可以使用闭包了:

function createCounter() 
{
  var counter = 0;
  function increment() 
  {
    counter = counter + 1;
    console.log("Number of events: " + counter);
  }
  return increment;
}
var counter1 = createCounter();
var counter2 = createCounter();
counter1(); // Number of events: 1
counter1(); // Number of events: 2
counter2(); // Number of events: 1
counter1(); // Number of events: 3

在代码中,我们创建了两个独立的计数器counter1与counter2,分别进行计数,互不干挠。代码看着有点奇怪,我们不妨拆分起来分析。

首先,我们来看看createCounter:
创建了一个局部变量counter
创建了一个局部函数increment(),它可以对counter变量进行加1操作。
将局部函数increment()返回。注意,返回的是函数本身,而不是函数调用的结果。
看起来,createCounter()函数与我们最初定义的计数器非常相似。唯一的不同点在于:createCounter()将计数器封装在一个函数内,于是我们将它称作闭包。

难以理解的一点在于,当我们使用createCounter()函数创建计数器时,实际上创建了一个新的函数:

// fancyNewCounter是一个新创建的函数
var fancyNewCounter = createCounter();

闭包的神奇之处在于。每次使用createCounter()函数创建计数器increment时,都会创建一个对应的counter变量。并且,返回的increment函数会始终记住counter变量。

更重要的是,这个counter变量是相互独立的。比如,当我们创建2个计数器时,每个计数器都会创建一个新的counter变量:

// 每个计数器都会从1开始计数
var counter1 = createCounter();
counter1(); // Number of events: 1
counter1(); // Number of events: 2
// 第1个计数器不会影响第2个计数器
var counter2 = createCounter();
counter2(); // Number of events: 1
// 第2个计数器不会影响第1个计数器
counter1(); // Number of events: 3

为计数器命名

多个计数器的输出信息都是“Number of events: N”,这样容易混淆。如果可以为每个计数器命名,则更加方便:

var catCounter = createCounter("cats");
var dogCounter = createCounter("dogs");
catCounter(); // Number of cats: 1
catCounter(); // Number of cats: 2
dogCounter(); // Number of dogs: 1

通过给createCounter传递一个新的counterName参数,可以很容易地做到这一点:

function createCounter(counterName) 
{
  var counter = 0;
  function increment() 
  {
    counter = counter + 1;
    console.log("Number of " + counterName + ": " + counter);
  }
  return increment;
}

这样,createCounter()函数返回的计数器将同时记住两个局部变量:counterName与counter。

优化计数器调用方式

按照之前的实现方式,我们通过调用createCounter()函数可以返回一个计数器,直接调用返回的计数器就可以加1,这样做并不直观。如果可以如下调用将更好:

var dogCounter = createCounter("dogs");
dogCounter.increment(); // Number of dogs: 1

实现代码:

function createCounter(counterName) 
{
  var counter = 0;
  function increment() 
  {
    counter = counter + 1;
    console.log("Number of " + counterName + ": " + counter);
  };
  return { increment : increment };
}

可知,以上的代码返回了一个对象,这个对象包含了一个increment方法。

添加decrement方法

现在,我们可以给计数器添加一个decrement()方法

function createCounter(counterName) 
{
  var counter = 0;
  function increment() 
  {
    counter = counter + 1;
    console.log("Number of " + counterName + ": " + counter);
  };
  function decrement() 
  {
    counter = counter - 1;
    console.log("Number of " + counterName + ": " + counter);
  };
  return {
    increment : increment,
    decrement : decrement
  };
}
var dogsCounter = createCounter("dogs");
dogsCounter.increment(); // Number of dogs: 1
dogsCounter.increment(); // Number of dogs: 2
dogsCounter.decrement(); // Number of dogs: 1

添加私有方法

前面的代码有两行重复的代码,即console.log语句。因此,我们可以创建一个display()方法用于打印counter的值:

function createCounter(counterName) 
{
  var counter = 0;
  function display() 
  {
    console.log("Number of " + counterName + ": " + counter);
  }
  function increment() 
  {
    counter = counter + 1;
    display();
  };
  function decrement() 
  {
    counter = counter - 1;
    display();
  };
  return {
    increment : increment,
    decrement : decrement
  };
}
var dogsCounter = createCounter("dogs");
dogsCounter.increment(); // Number of dogs: 1
dogsCounter.increment(); // Number of dogs: 2
dogsCounter.decrement(); // Number of dogs: 1

看起来,display()函数与increment()函数以及decrement()函数差不多,但是其实它们很不一样。我们并没有将display()函数添加到返回的对象中,这就意味着以下代码会出错:

var dogsCounter = createCounter("dogs");
dogsCounter.display(); // ERROR !!!

这时,display()相当于一个私有方法,我们只能在createCounter()函数内使用它。

闭包与面向对象编程

如果你接触过面向对象编程(OOP),则应该不难发现本文中所涉及的内容与OOP中的类、对象、对象属性、共有方法与私有方法等概念非常相似。
闭包,与OOP相似,就是把数据和操作数据的方法绑定起来。因此,在需要OOP的时候,就可以使用闭包来实现。

总结

闭包(Closure)是JavaScript一个非常棒的特性。掌握它,我们可以从容应对一些常见的编程需求。

版权声明: 转载时请注明作者Fundebug以及本文地址: https://blog.fundebug.com/2017/07/31/javascript-closure/
Posted in 精彩内容 | 解密JavaScript闭包已关闭评论