分类 前端技术 下的文章

话说这连天在修改原来老前辈留下来的js代码的时候,一不小心就遇到了一个蛋疼的问题,这里我就简单的抽象出一个模拟的栗子来,大概就是下面这个样子:


$("body").append("<textarea rows=6></textarea>");
console.log($("textarea").height());

差不多就是这样吧,so,console的结果是?


是红果果的0呀,有木有!! 后来就找公司大牛给解释一下,这货很淡定的在我的代码上加了这样一句:


setTimeout(function(){
    console.log($("textarea").height());
},0);

然后这个高度就毫无节操的跳出来了。。。


难道这个setTImeout(0)不就是立即执行的意思么?

蓝后捏,我就蛋疼的做了个实验:


console.log(1);
setTimeout(function(){
    console.log(2);
},0);
console.log(3);

so,结果捏?


嗯嗯,结果是 1 , 3 , 2  。。。。

好吧,这大概就可以解释一些东西了,当我在给body添加一个元素的之后,立刻去取这个元素的高度的时候,这时候js的这个添加的函数还没有完全执行完,虽然DOM中已经有了,但是浏览器也还没有渲染完成,所以这时候的取值是不正确的,而etTimeout之后,取值的操作就会被js放到下一个event loop中去执行,此时的添加和渲染DOM的操作都已经完成了,也就可以得到正确的结果了。。。

百度了一下,发现setTimeout(0)的应用还是挺广泛的,嗯嗯,看来以后要多多注意这些东西了~

嗯嗯,不过以上都是个人看法,如果有哪里理解有偏差的话,还是希望在大牛在留言里及时指出,嗯嗯~

好啦,就先到这吧,话说这几天好热,整个人都化了,木精神~ =.=!

嗯嗯,要是以后还发现其他的用处的话,应该还有后续滚动~ 嗯嗯,就这个样子~

今天晚上闲下来想去试试Jquery的animate函数,本来想随便写个看看效果,兰侯就去吃饭的,结果。。。。

先来看看刚开始写的吧


<html>
<head>
	<script src="http://code.jquery.com/jquery-1.9.1.min.js" language="Javascript"></script>
	<script>
		$(function(){
			$(".green").click(function(){
				$(this).animate({top : "300px"},300,"linear",function(){
					thi = $(this);
					setTimeout(function(){
						thi.animate({top : "100px"},300);
					},1000);
				});
			});
		})
	</script>
	<style>
		.green{
			position : relative;
			float : left;
			top : 100px;
			left : 200px;
			margin : 10px;
			height : 100px;
			width : 100px;
			background-color : green;
		}
	</style>
</head>
<body>
	<div class="green"></div>
</body>
</html>

特别简单的代码,就是看看animate的效果,木有其他的想法,运行起来也木有问题。。。


本来这样就行了嘛,大家都好好的,结果,好吧,我手贱了,我多加了两个div,然后就。。。。


<html>
<head>
	<script src="http://code.jquery.com/jquery-1.9.1.min.js" language="Javascript"></script>
	<script>
		$(function(){
			$(".green").click(function(){
				$(this).animate({top : "300px"},300,"linear",function(){
					thi = $(this);
					thi.html("111");
					setTimeout(function(){
						thi.html("222");
						thi.animate({top : "100px"},300);
					},1000);
				});
			});
		})
	</script>
	<style>
		.green{
			position : relative;
			float : left;
			top : 100px;
			left : 200px;
			margin : 10px;
			height : 100px;
			width : 100px;
			background-color : green;
		}
	</style>
</head>
<body>
	<div class="green"></div>
	<div class="green"></div>
	<div class="green"></div>
</body>
</html>

额,当我快速将三个div都点击下去之后,好吧,我惊喜的发现只有最后一个起来了,而前两个都木有反应啊。。。。


蛋疼的人总是这样,然后就找原因呗,寻思了一下,感觉是因为setTimeout里使用的thi变量被覆盖的缘故。。。。

加了个输出后发现,应该就是这个的缘故,但是这是为什么呢?不是应该互不影响的么?

晚上睡觉的时候,我突然间想到一件事,没有用var声明的变量会变成全局变量,会不会是因为这个? 果断起来试了一下,问题就这么解决了。。。。

<html>
<head>
	<script src="http://code.jquery.com/jquery-1.9.1.min.js" language="Javascript"></script>
	<script>
		$(function(){
			$(".green").click(function(){
				$(this).animate({top : "300px"},300,"linear",function(){
					var thi = $(this);
					thi.html("111");
					setTimeout(function(){
						thi.html("222");
						thi.animate({top : "100px"},300);
					},1000);
				});
			});
		})
	</script>
	<style>
		.green{
			position : relative;
			float : left;
			top : 100px;
			left : 200px;
			margin : 10px;
			height : 100px;
			width : 100px;
			background-color : green;
		}
	</style>
</head>
<body>
	<div class="green"></div>
	<div class="green"></div>
	<div class="green"></div>
</body>
</html>

好吧,一失足成千古恨,我就是一个失足少年呀~  现在觉的前端的编程规范真的很重要,以后要好好学习了。。。。


再兰候就是博客升了个级,貌似代码运行的插件不能用了,就先这样吧,最近也在准备弄VPS,博客这就先这样了,以后有时间了再好好弄弄。。。


就是这样。。。。 嗯嗯。。。。

<p>先声明一下,以下内容完全是个人经验的认识,并不保证正确,不要误导了还在茁壮成长的童鞋~</p>
<p> </p>
<p>此事说来话长,话说从盘古开天辟的时候。。。(这你妹也太长了点儿吧。。。)</p>
<p>=。=!  好吧好吧,其实就是昨天,办公室里的一个师哥在研究JS的闭包,然后就追溯到了JS变量的作用域链,并且最后弄出了这样一段代码:</p>
<p></p>

function makefunc(x) { 
  return function() { 
    return x; 
  }
}
var a = [makefunc(0), makefunc(1), makefunc(2)]; 
alert(a[0]()); 
alert(a[1]()); 
alert(a[2]());
<p></p> <p>结果就是分别弹出:0,1,2</p> <p> 这里就看出了,makefunc这个函数每次返回的函数都是相同的,但是,返回的函数的执行环境不同,也就是说这个函数所处的作用域链是不同的。。。</p> <p>当每次执行makefunc这个函数时,返回的是一个相同的匿名函数和这个匿名函数执行所需要的环境的综合体,这也就是传说中的闭包~ (主角终于登场了~)</p> <p> 那么我们就可以看出,数组a的每一个元素,其实都是一个function,用a[0]()这样的方式来执行它,从而得到了上面的结果,那当我们console.log出数组a的时候(不晓得用console.log出来的结果是不是足以证明一下的结论。。。。),我们发现它的每个元素里面都带有这个function执行时需要的变量x,也就是其实在a数组中的每个元素都是有他的完整的一套执行代码和运行空间,也就是闭包的真面目。。。。。</p> <p>那然后呢,我们俩个有继续巴拉巴拉。。。。。  说道作用域,又说道JS代码在执行时变量的存储和回收,于是就出现了下面这段代码:</p> <p></p>
var a = 10;
function b(){
    a = 3;
    function a(){}
}
b();
alert(a);
<p></p> <p>嘿嘿,看官们觉的这段代码的弹出结果是什么捏?</p> <p>function ? 不对~   3 ?  不对~  是10~!</p> <p>有木有,它竟然是10~! 你让函数里面那两个a情何以堪啊~</p> <p>那这是为什么捏? 其实还是比较简单的,是因为js在执行前,会先扫描一下全文,把用到的变量先在作用域的开头做一次声明,也就是我们看到的function a(),它的作用域是整个b函数,我们也知道</p> <p>function a(){} 和 var a = function(){} 是一样的,所以其实上面的代码在js的执行顺序是这样的</p> <p></p>
var a = 10;
function b(){
    var a ;
    a = 3;
    a = function(){};
}
b();
alert(a);
<p></p> <p>亲们,这下看出来了吧,函数里面的变量a在函数执行完后被回收,所以,下面的弹窗是显示的最开始的a的值。。。。。</p> <p>额,好吧,总觉得js的这个做法有些坑,但是还挺好玩的~</p> <p>那么,现在我们弄明白了js的作用域、作用域链以及传说中强大的闭包,那么我们就写个封装在闭包里的函数吧~</p> <p></p>
(function(){
  .........
})();
<p></p> <p>诶~ 诶~ 诶~ 等会儿~ function外面的那个小括号是干什么滴捏?</p> <p>封装闭包呀~封装闭包为什么要有一个小括号捏?话说没有那个小括号的话,function就不是闭包了?这个小括号在这里到底起了什么作用捏?(。。。。。  这。。。。  我还以为要结束了呢,怎么又来这么多问题?!)(所以才说是引发的“血案”啊~)</p> <p>好吧,那就再看看这个传说中的小括号吧~</p> <p>那么首先我们知道:</p> <p></p>
(fucntion(){alert(1);})();
<p></p> <p>这样写的话,里面的匿名function是会被执行的,那么当我们把小括号去掉呢?  </p> <p></p>
function(){alert(1);}();
好吧,我承认他执行不了。。。 = =!<p></p> <p>话说那去掉括号后要怎么样才会执行呢? 很明显给它加函数名调用嘛~</p> <p></p>
function a(){alert(1);};
a();
额,好吧,那话说我加上括号的话,再这样调用呢?<p></p> <p></p>
(function a(){alert(1)});
a();
哎呦喂~  竟然提示说a未定义~  这。。。。。<p></p> <p>那我们把里面的函数赋给一个全局变量会怎么样呢?</p> <p></p>
var a;
(a = function(){alert(1);});
a();
好吧,它执行了也就是说原来的代码在小括号作用完成后,里面的a被回收了。。。。<p></p> <p>经过翻阅资料,发现这里的小括号的作用是强制表达式运算,那么,也就是说它会让里面的表达式强制性进行一遍运算~</p> <p>那么,大概可以猜测上面的小括号的作用应该是类似于下面的代码</p> <p></p>
function (){
  return function (){alert(1);};
}
也就是说小括号运算结束后,把里面的a函数以匿名函数的方式返回回来,而返回的匿名函数实际上就是一个有执行代码和执行环境的一个闭包,这样,也就是实现了把方法封装到一个闭包里了。。。。<p></p> <p>然后放出两个查到的资料:</p> <p>JS小括号的作用</p> <p>JS声明变量的原理</p> <p> </p> <p>然后捏,上一张”闭包“的果照~(哇哈哈哈哈哈~)</p> <p> </p> <p> </p> <p>哇哈哈哈哈~  很上镜哦~</p> <p> </p> <p> </p> <p>最后,惯有的唠叨几句:</p> <p>话说再过两天就要回家了呀~  小心情还是很鸡冻滴~  还是觉的这个寒假要好好珍惜,嗯嗯~  多的就先不啰嗦了,等回家有时间再说吧~  嗯嗯,今天就到这里吧~  </p> <p>对了~  我觉得我得求一份工作了~  六月份就毕业了,o(︶︿︶)o 唉~  桑不起呀~  </p> <p>好了好了,就到了这了,还是祝大家都开心哈~</p> [1]: https://secbone.com/usr/uploads/2015/08/1171503046.jpg

    还久没更新了,主要是对新的项目木有头绪,感觉手足无措呀。。。。

    最近一直在纠结于jquery选择器的问题,昨天经小松哥点拨,写了个关于jquery选择兄弟元素的小demo,虽然还没有解决我现在的问题,但是还是放出来分享一下:

    兄弟元素选择主要是用siblings()这个函数,使用方法如下:

    $("#aa").siblings().click(.....)    就是说选择id为aa的元素的所有同级的兄弟元素添加click事件,但是只有同级的。

    小demo如下:


嗯嗯,就是这个样子啦。。。。。

话说就快要过年了,我的实习也快要结束了,嗯嗯,加油了,大家都加油喽~

对了,再次鸣谢一下小松哥~  o(∩_∩)o 哈哈

<p>话说今天调了一个bug,先叙述一下过程吧:</p>
<p></p>

if(!Array.prototype.indexOf){
    Array.prototype.indexOf = function(obj){
        for(var i=0; i&lt;this.length; i++){
            if(this[i]==obj){
                return i;
            }
        }
        return -1;
    }
}

<p> 这段代码估计很多人用过吧,他是用来解决IE下没有indexOf这个问题的,也就是因为这段代码,才出现的IE下for in的问题(好吧,都是万恶的IE。。。。。)</p>
<p>当还没加上这段代码的时候</p>

var a = [1,2,3];
for( var k in a){
    alert(a[k]);
}

这样没有任何问题,结果是1,2,3。。。。<p></p>
<p>但是,当加上上面的代码时,奇迹就发生了,他会先打出上面的function,然后再1,2,3。。。。。。</p>
<p>额。。。  神一样的蛋疼。。。</p>
<p>大概的意思就是IE下用for in的时候,不光会遍历出数组的值,还会遍历出你新添加的方法。。。。  </p>
<p>所以,大家以后在IE下用for in请小心喽~</p>
<p>解决办法嘛,目前我想到的就是加一个判断:</p>

for( var k in a){
    if( k == "indexOf")
        continue;
    .........
}

<p>或者是:</p>

for( var k in a){
    if(!isNaN(k)){
        .........
    }
}

大概就是这个样子,如果高手有好的方法的话,希望留言告诉我一下,先在这儿谢谢啦~<p></p>
<p>嗯嗯,差不多就这个样子,然后就是,话说这个周五要世界末日了,亲们还有什么想做的赶紧去行动吧~</p>

话说今天闲着没事,写着玩的,放出来看看,很简单,但是效果还不错

上代码:


嗯嗯,就是这样~

这是在别的地方翻到的代码,但是它原来的有一点小问题,自己把它改进了一下,发出来标记一下,方便自己以后找。。

function numberFormat(num, decimal, dec, spe) { 
     decimal = (undefined === decimal) ? 0 : decimal; 
     decimal = parseInt(decimal); 
     dec  = (undefined === dec) ? '.' : dec; 
     spe  = (undefined === spe) ? ',' : spe; 
     num  = parseFloat(num) + ''; 
 
     var length, tmp, left, right; 
     length = num.length; 
     tmp  = num.split('.', 2); 
     left = tmp[0]; 
     left = _split(left, 3, spe); 
 
     right = (undefined === tmp[1]) ? '' : tmp[1]; 
     right = _pad(right, decimal); 
 
     if (0 == right.length) { 
         num = left; 
     } else { 
         num = left + dec + right; 
     } 
 
     return num; 
 
     function _split(str, len, spe) { 
         var l  = str.length; 
         var tmp = new Array(); 
    
         if (l > len) { 
             var b = l % len; 
 			if(b == 0)
 				b = len;
             var ts = str.substr(0, b); 
             tmp.push(ts); 
    
             while (b < l) { 
                 var ts = str.substr(b, len); 
                 tmp.push(ts); 
                 b += len; 
            } 
           str = tmp.join(spe); 
       } 
    
         return str; 
     } 
    
     function _pad(str, len) { 
         var l = str.length; 
    
         if (l < len) { 
             for (var i = 0; i < (len - l); i++) { 
                  str += '0'; 
            } 
        } else { 
               str = str.substr(0, len); 
        } 
    
         return str; 
     } 
 }

嗯嗯  numberFormat(num, decimal, dec, spe)  

第一个参数是要格式化的数字,

第二个参数是小数点后的位数(可选,默认0),

第三个参数是小数点的样式(可选,默认'.'),

第四个参数是分隔符的样式(可选,默认',')

 

嗯嗯  来个例子:numberFormat(1234,2);  输出为  1,234.00

嗯嗯 大概就是这个样子~

radio的onchange函数大家应该都知道,但是今天小菜才发现这个很常用的函数在ie下的行为与其他浏览器的行为存在不一致性。

在FF,Chrome下,只要radio发生改变,onchange函数就会触发,而在IE下则是要等到radio失去焦点时onchange函数才会触发。

下面是一个简单的例子:


从这里我们可以看到,在FF,Chrome下,只要鼠标点击一个radio时,onchange就触发了,而在IE下时,当你点击一个radio时,onchange函数并没有触发,而是在你点击空白地方,radio失去焦点时才触发了。而且这个现象在IE6、7、8中都存在(IE9没有测试,IE10里已经没有问题了。。。)

那我们要怎么去解决这个问题呢?

我们可以在radio上加一个onclick函数来解决:

<input type="radio" name="aa" value="1" onchange="alert(1)" onClick="this.blur();">

如果你是用jquery做的话,在1.3.2里面也是会有这个问题的,在1.4.2就没问题了

当然,你也可以要求用户告别IE6~(o(∩_∩)o 哈哈~,貌似这是前端人士的心声呀~)

 

嗯嗯,就是这样,有不对的地方还请大家多多指教哈~

    这篇日志主要是给自己mark一下,留着以后有用的时候方便找的,下面贴代码:

    var x = document.documentElement.scrollLeft + e.clientX;

    var y = document.documentElement.scrollTop + e.clientY;

 

    以上方法可以兼容IE6的鼠标位置,然后用jquery获取元素位置即可得出鼠标的相对位置来,下面再贴张图,虽然我还没看懂,不过估计有用,先留着~

 

    点击查看原图

 

    嗯嗯,就这么多~

    一直以来浮动就是做css里面很让人蛋疼的问题,所以,我一直是很小心的使用着它,生怕这货会给我惹出点儿事端来。。。

    而经过一段时间的使用,也发现了一些比较好的驾驭浮动的方法,最常见的便是clear:both。。。这个就不多说了,一般人都懂得。

    最近才得知overflow和zoom能清除浮动,所以果断的使用了一下,发现效果真是刚刚的~  所以也喜欢上了用这两个属性来清除浮动,但是一直对它们清除浮动的原理很不解,所以就狠狠的百度了一个小时,直到看到某位大神提出的“包裹”这个思想,让我觉得一下子明朗了不少,所以来和大家分享一下。。。。(= =! 今天的开场白貌似有点长。。。。)

    首先先说overflow吧,overflow:hidden有一个大家都知道的作用就是溢出隐藏,也就是在父元素设置了宽和高以后,子元素的内容如果有溢出的话,就隐藏溢出部分,不予显示(额,由于今天比较晚了,我就不写demo了,纯口述。。。)

    那么,如果父元素设置了overflow:hidden属性后,又不给它设置宽和高的话,会怎么样呢? 首先我们来想一下,如果父元素没有设置宽和高,而子元素没有float属性的话,那么很简单,父元素会被子元素撑开。那要是子元素是float属性呢?按理来说,父元素会瘪成0高0宽,因为我前面有篇日志说过,float是脱离了原来的层而单独浮在上面的。但是我们想一下,子元素浮在外面,父元素又没有体积,按照overflow:hidden来说,也就是说子元素全部溢出,也就是全部隐藏。。。。  这怎么想怎么觉的不太合情理,所以这里的父元素就需要去包裹住这个浮动的子元素,也就出现了我们所看到了清除浮动的效果。。。

    至于zoom:1呢,这真是一个特别神奇的属性,简直就是IE下的神器~(预知详情,以后有时间我再写吧,这次主要写它的清除浮动的作用。。。。 =。=)  这个属性最开始是用于缩放的,后面跟的参数就是缩放比例。那么让我们再回到上面所说的情景:父元素设置了zoom,无高无宽,而子元素又是float,那么父元素又是一个零体积,这时候要进行缩放的话,因为零怎么按比例缩放都是零,所以,父元素也只能去包裹它的子元素,然后才能进行缩放。。。

    然后是兼容性,zoom属性大家都是到,是只有IE下有效的,而overflow呢,在IE6下的时候,微软对overflow的理解有误,所以没有清除浮动的作用,从IE7开始修就正好了。。。。还有一点就是,overflow做清除浮动的时候,貌似会有占tab键的情况发生,所以还是按情况使用。。。。

    嗯嗯,大概就是这么的,以上纯属小菜个人理解,有不对的地方还请大牛们多多指正~

    

    PS:不早了,敲完收工回宿舍喽~