迁移其他js文章之二

三十一、js检查一个数值是整数还是浮点数

<script>
function isInt(n) {
   return typeof n === 'number' && n % 1 == 0;
}


function isFloat (n) {
  return n===+n && n!==(n|0);
}

console.log(isInt(3));
console.log(isInt(3.3));
console.log(isFloat(3));
console.log(isFloat(3.3));
</script>

怎么样,简单而高效,执行结果:

image.png

三十二、javascript跳出双重循环

function foo ()
{
    abc:
    for(var k = 0; k < 4; k++){
        for(var m = 0; m < 4; m++){
            if(m == 2){
                break abc;
            }
        }
    }
}

三十三、js获取浏览器类型和版本

<script>
function getBrowserInfo(){
    var Sys = {};
    var ua = navigator.userAgent.toLowerCase();
    if (window.ActiveXObject){
        Sys.b="ie";
        Sys.v =parseInt(ua.match(/msie ([\d.]+)/)[1]);
    }
    else if (document.getBoxObjectFor){
        Sys.b="firefox";
        Sys.v =parseInt(ua.match(/firefox\/([\d.]+)/)[1]);
    }
    else if (window.MessageEvent && !document.getBoxObjectFor){
        Sys.b="chrome";
        Sys.v == parseInt(ua.match(/chrome\/([\d.]+)/)[1]);
    }
    else if (window.opera){
        Sys.b="opera";
        Sys.v == parseInt(ua.match(/opera.([\d.]+)/)[1]);
    }
    else if (window.openDatabase){
        Sys.b="safari";
        Sys.v == parseInt(ua.match(/version\/([\d.]+)/)[1]);
    }
    return Sys;
}

var bi=getBrowserInfo();
console.log("Browser:"+bi.b+"    Version:"+bi.v);
</script>

以上代码可以用于获取浏览器的类型以及主版本信息。

三十四、element.scrollHeight

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>用JavaScript添加和删除class</title>
<script src="jquery-1.12.4.min.js"></script>
<style>
	.cont {
	  overflow: hidden;
	  width:200px;
	  border:1px solid black;
	  max-height: 0;
	}
</style>
</head>
<body>
	<div class="cont">我是详细内容我是详细内容我是详细内容我是详细内容我是详细内容我是详细内容我是详细内容我是详细内容
		我是详细内容我是详细内容我是详细内容我是详细内容我是详细内容我是详细内容我是详细内
		容我是详细内容我是详细内容
		</div>
</body>
<script>
	var el = document.querySelector('.cont')
	var height = el.scrollHeight;
	alert(height);//189
</script>
</html>

如上:

image.png

el.scrollHeight是包含溢出的元素的高度,它将根据元素的内容动态更改。这里演示的是即便你通过max-height把其高度设置为不显示,通过scrollHeight也可以获取到元素总的高度(包含能显示的高度+滚动出去的高度)

三十五、如何使用js或者jquery判断图片加载完毕?

        使用js的onload事件可以判断不假,比如写成window.οnlοad=function(){},这样会当整个文档的图片都加载完才能执行fujnction里面的逻辑,跟判断某一个图片加载完毕是不一样的,如果想要使用JavaScript来判断某个图片是否加载完成,可以在被判断的图片上增加onload事件。而使用jquery的load事件只是dom执行完毕,图片未必加载完成,如果要判断图片加载完毕,则需要在图片标签上增加jquery的load事件。

示例代码如下

js:

img.onload = function() {
    alert('img图片加载完毕' );
};

jquery:

$('img').on('load', function() {
    alert('img图片加载完毕: ' + this.src);
});

三十六、js实现自适应横向瀑布流

瀑布流效果是图片展示中很常用的一种特效,分为横向瀑布流展示和纵向瀑布流展示,这里我们来看看如何使用jquery实现横向瀑布流特效呢?效果如图:

image.png

本案例结合baguetteBox.js与jquery实现。

因为涉及到的代码太多,我在这里只贴出index.html里面的JavaScript,其他打包下载吧,各位:

<script>
 baguetteBox.run('.gallery', {
  // 配置参数
  buttons:Boolean,//是否显示导航按钮。
  noScrollbars:true,//是否在显示时隐藏滚动条。
  titleTag:true,//是否使用图片上的title属性作为图片标题
  async:false,//是否异步加载文件。

  afterShow:function(){//显示遮罩层之后的回调函数。   
       $(".pressing").fadeIn();
    },
  afterHide:function(){//隐藏遮罩层之后的回调函数。 
      $(".pressing").fadeOut(); 
    }
  //preload:5 预加载多少个文件。
  // onChange: function(currentIndex, imagesCount){} 图片改变时的回调函数 
  // overlayBackgroundColor:'rgba(0,0,0,0.8)' 遮罩层的背景颜色
});

$(function(){

    //返回顶部 
    $(window).scroll(function(){
        var sc=$(window).scrollTop();
        var rwidth=$(window).width()
        if(sc>500){
            $("#goTopBtn").css("display","block");
            $("#goTopBtn").css("left",(rwidth-106)+"px")
        }else{
            $("#goTopBtn").css("display","none");
        }
    })
    $("#goTopBtn").click(function(){
        var sc=$(window).scrollTop();
        $('body,html').animate({scrollTop:0},100);
    })

    $(".allnews").click(function () {
        $("#allcon").css("height", "auto");
        $(this).hide(1000);
    });
})

</script>

三十七、js里面的元素节点、属性节点、文本节点

js里面的元素节点、属性节点、文本节点,下面的例子演示了在javascript中操作这三种节点的方法。

html:

用户名:<input name="uname" style="color: red;border-bottom-color: blue;height: 9px;"/>
<p>你想到哪个国家去旅游?</p>
<ul id="country">
	s<li id="china">中国</li> 
    <li>印度</li>  
	 <li>泰国</li> 
	 <li>巴西</li> 
</ul>

javascript:

<script type="text/javascript" >
//元素节点、属性节点、文本节点
window.onload=function(){
	var inputNodes=document.getElementsByName("uname");
	var unameInput=inputNodes[0];
	//js操作属性可直接通过.的方式
	console.log(unameInput.style.height);//输出:9px
	
	var c=document.getElementById("country");
	//得到所有子节点 ,这里的子节点可能是元素节点也可能是文本节点
	var subAll=c.childNodes;
	console.log(subAll.length);//输出:9
	console.log(c.firstChild);//输出: s 
	console.log(c.lastChild);//输出: #text
	//获取元素子节点
	var elementsons=c.getElementsByTagName("li");
	console.log(elementsons.length); //输出: 4
	//获取文本子节点
	var textSubNode=document.getElementById("china").firstChild;
	//通过nodeValue来操作文本
	console.log("textSubNode的文本是:"+textSubNode.nodeValue);
	textSubNode.nodeValue="大中国";
}
</script>

执行结果:

image.png

三十八、使用javascript原生代码实现全选/全不选

        如果让你实现全选/全不选这种功能,网上铺天盖地的代码肯定是让你看的眼花缭乱的,因为这种特效真是太常用而且也是很容易实现的,使用jquery你可以在三四行之内就完成这个功能,今天我们要说的是使用原生的javascript如何实现这个功能,送给有需要的同学。

先看最终效果图:

全选状态q全不选状态
image.pngimage.png

好,效果就是上面这样,我们来看如何实现。

html:

<body>
	选择你爱好的运动:<input type="checkbox" id="cb"/>全选/全不选<br/>
	<input type="checkbox" name="items">足球
	<input type="checkbox" name="items">篮球
	<input type="checkbox" name="items">乒乓球
	<input type="checkbox" name="items">网球
	<input type="checkbox" name="items">橄榄球
</body>

javascript:

<script type="text/javascript">
	window.onload = function() {
		//1.选项点击处理
		var checkboxItems=document.getElementsByName("items");
		for(var i=0;i<checkboxItems.length;i++){
			checkboxItems[i].onclick=function (){
				//存放被选择的复选框的数量,包含刚被点击的
				var hasSelectedCount=0;
				for(var i=0;i<checkboxItems.length;i++){
					if(checkboxItems[i].checked){
						hasSelectedCount++;
					}
				}
				if(hasSelectedCount==checkboxItems.length){
					document.getElementById("cb").checked=true;
				}else{
					document.getElementById("cb").checked=false;
					
				}
			}
		}
		
		//2.全选/全不选单击处理
		var cbNode=document.getElementById("cb");
		//alert(cbNode.checked);
		cbNode.onclick=function (){
			//比如原先没选,刚才点击选了,到这一步的时候就是true了
			if(cbNode.checked){
				var itemsNodes=document.getElementsByName("items");
				for(var i=0;i<itemsNodes.length;i++){
					itemsNodes[i].checked=true;
				}
			}else{
				var itemsNodes=document.getElementsByName("items");
				for(var i=0;i<itemsNodes.length;i++){
					itemsNodes[i].checked=false;
				}
			}
		}
	}
</script>

三十九、js点击事件onclick实战

实现效果,我们用一张动态图来说明:

GIF.gif

需求描述:点击li元素,如果文字含有"^^"则去掉,没有就加上。

html:

<p>你想到哪个国家去旅游?</p>
<ul id="country">
	<li id="china">中国</li> 
    <li>印度</li>  
    <li>泰国</li> 
	 <li>巴西</li> 
</ul>

javascript:

<script type="text/javascript">
window.onload=function(){
	var c=document.getElementById("country");
	var elementsons=c.getElementsByTagName("li");
	for(var i=0;i<elementsons.length;i++){
		var liElement=elementsons[i];
		liElement.onclick=function (){
			var text=this.firstChild.nodeValue;
			var reg=/^\^{2}/g;
			if(reg.test(text)){//li的内容包含"^^"就替换"^^"为""
				//这里别忘了用text接收
				text=text.replace(reg,"");
				this.firstChild.nodeValue=text;
			}else{
				text="^^"+text;//li的内容不包含"^^"就在前边添加
				this.firstChild.nodeValue=text;
			}
		}
	}
}
</script>

 

四十、nodeType,nodeName,nodeValue是啥意思

nodeType,nodeName,nodeValue这三个属性针对元素节点、属性节点、文本节点这三类节点(node)是不同的,下面的代码带你了解它们之间组合的异同。

html:

<p>你想到哪个国家去旅游?</p>
<ul id="country">
	<li id="china">中国</li> 
    <li>印度</li>  
    <li>泰国</li> 
	 <li>巴西</li> 
</ul>

javascript:

<script type="text/javascript">
//Node的属性:nodeType/nodeName/nodeValue
window.onload=function(){
	console.log("document.nodeValue:")
	console.log(document.nodeValue);
	var c=document.getElementById("china");
	console.log("元素节点的nodeType,nodeName,nodeValue三个属性值:");
	console.log(c.nodeType);//1
	console.log(c.nodeName);//li
	console.log(c.nodeValue);//null
	console.log("属性节点的nodeType,nodeName,nodeValue三个属性值:");
	var cId=c.getAttributeNode("id");
	console.log(cId.nodeType);//2
	console.log(cId.nodeName);//id
	console.log(cId.nodeValue);//china
	console.log("文本节点的nodeType,nodeName,nodeValue三个属性值:");
	var text=c.firstChild;
	console.log(text.nodeType);//3
	console.log(text.nodeName);//#text
	console.log(text.nodeValue);//中国
	console.log("文本节点时innerHTML与nodeValue相同:");
   var china=	document.getElementById("china");
   console.log(china.firstChild.nodeValue);
   console.log(china.innerHTML);
}
</script>

输出结果:

image.png

总结下呗:

        元素节点的nodeType是1,属性节点的nodeType是2,文本节点的nodeType是3。通过nodeType属性我们可以判断节点的类型。

四十一、createElement,createTextNode,appendChild的用法实战

我们通过下面这个例子:

GIF.gif

来看看javascript中createElement,createTextNode,appendChild这几个方法的用法。

需求描述:点击提交,会在对应的ul列表下附加输入的内容,附加输入的内容这里就要用到js中如何创建元素标签、如何在创建的元素标签上创建文本,以及如何把组装好的新标签附加到已有document上。

下面是html代码:

<p>你想到哪个国家去旅游?</p>
	<ul id="country">
		<li id="china">中国</li>
		<li>印度</li>
		<li>泰国</li>
		<li>巴西</li>
	</ul>
	<p>你喜欢哪种水果?</p>
	<ul id="fruit">
		<li>苹果</li>
		<li>栗子</li>
		<li>香蕉</li>
		<li>葡萄</li>
	</ul>
	<input type="radio" name="typetocheck" id="c" value="country"/>国家
	<input type="radio" name="typetocheck" id="f" value="fruit"/>水果
	<input type="text" id="uname"/>
	<input id="btn" type="button" value="提交" />

javascript:

<script type="text/javascript">
	window.onload = function() {
		var btn = document.getElementById("btn");
		btn.onclick = function() {
			var flag = false;
			var selected;
			var radios = document.getElementsByName("typetocheck");
			for ( var i = 0; i < radios.length; i++) {
				var oneradio = radios[i];
				if (oneradio.checked) {
					flag = true;
					//这种方式是通过属性节点来访问,弄混了one.getattributeNode("id").nodeVALUE
					//selected=oneradio.id.nodeValue;
					//selected=oneradio.id;
					//用value属性更通用
					selected=oneradio.value;
					break;
				}
			}
			if (!flag) {
				alert("至少选择一种类型");
				return false;
			}
			//选择类型后
			var uname=document.getElementById("uname");
			if(uname.value==null||uname.value==""){
				alert("请输入内容");
				return;
			}
			//var reg=/\s/g;
			var reg=/\s*/g;//*表示》=0个
			var texttoappend=uname.value;
			if( reg.test(texttoappend)){
				uname.value=uname.value.replace(reg,"");
			}
			//把去除空格之后的值再赋给这个变量
			texttoappend=uname.value;
			var liNode=document.createElement("li");
			//创建文本节点
			var textNode=document.createTextNode(texttoappend);
			liNode.appendChild(textNode);
			var parent;
			/*if(selected=="c"){
			parent= document.getElementById("country");	
			}else{
			parent= document.getElementById("fruit");	
			}*/
			parent= document.getElementById(selected);	
			parent.appendChild(liNode);
		}
	}
</script>

 

四十二、removeChild,insertBefore用法

案例:

image.png

通过这个案例,我们学习一下如何使用javascript删除元素,以及在指定位置插入元素,这些方法都是javascript操作dom元素必须掌握的。主要使用的javascript中的removeChild,insertBefore方法

html:

<p>你想到哪个国家去旅游?</p>
	<ul id="country">
		<li id="china">中国</li>
		<li>印度</li>
		<li>泰国</li>
		<li>巴西</li>
	</ul>
	<p>你喜欢哪种水果?</p>
	<ul id="fruit">
		<li id="apple">苹果</li>
		<li>栗子</li>
		<li id="banana">香蕉</li>
		<li>葡萄</li>
	</ul>
	<input type="button"  value="删除中国">
	<input type="button"  value="在香蕉前面加入葡萄节点">

javascript:

<script type="text/javascript">
//节点的删除和指定位置的插入
	window.onload = function() {
	var btn= document.getElementsByTagName("input")[0];
	btn.onclick=function(){
		var chinaLi=document.getElementById("china");
		var pchina=chinaLi.parentNode;
		pchina.removeChild(chinaLi);
    	}
	
	document.getElementsByTagName("input")[1].onclick=function(){
		
	var pbanana=document.getElementById("banana").parentNode;
	var liputao=document.createElement("li");
	var textputao=document.createTextNode("葡萄");
	liputao.appendChild(textputao);
	pbanana.insertBefore(liputao,document.getElementById("banana") );
	}
	
	}
</script>

四十三、js学习笔记分享3之Bom对象和现代事件绑定

又找到一篇学习笔记,多看注释:

<a href="javascript:void(0)" onclick="javascript:f1()">测试location的assign</a>
	<a href="#" onclick="javascript:f2()">测试location的replace</a>

javascript笔记:

<script type="text/javascript" >
/*
alert(window);//[object Window]
alert(typeof window);
*/
//window对象时最顶层的:
/*
 * window的属性:
	 document     history   location    opener      navigator   screen      frames
	 --document的属性:location forms   links anchors  images
 */
  //window的重要方法:打开的窗口对象 =open():url name/方式    选项
//  window.open("http://www.baidu.com");//每次都打开一个新的
  // window.open("http://www.baidu.com","first");  //打开过一次后,每次打开都会在这个tab里面打开
    //  window.open("http://www.baidu.com","first","width=300,height=300;top=10,left=10,toolbar=yes");
    //打开过一次后,每次打开都会在这个tab里面打开
    //oepn方法的返回值是打开的窗口对象window
    /*
  	var newWindowObj=window.open("http://www.baidu.com","first");
    alert(newWindowObj);//[object Window]
    newWindowObj.alert("用新窗口弹出字符串");
    */
    //测试opener
   // window.open("opened.jsp","first");
    
    
    //typeof一个未声明的变量undefined
    //alert(typeof age);
    
    
    //窗口的位置和大小
    /*
    var leftX=typeof window.screenLeft=="number"?screenLeft:screenX;//左边距,后边的只有ff支持
    var lefty=typeof window.screenTop=="number"?screenTop:screenY;//上边距
    //视口的大小,也就是操作被限定的区域,相当于工作空间
    var width=typeof innerWidth=="number"?innerWidth:document.documentElement.clientWidth;//前边的ie不支持
    var height=typeof innerHeight=="number"?innerHeight:document.documentElement.clientHeight;
    alert(leftX+" "+lefty+"  "+width+"   "+height);
    */
    
    //location对象
    //alert( location instanceof Location);
    //截取?和?后面的
    /*		
    alert(location.search);//http://localhost:8080/front/source/js6.jsp?id=3&name="jack"
    alert(location.search.length);//http://localhost:8080/front/source/js6.jsp?id=3&name="jack"
    */
    //页面重新加载
   // location.reload(true);//true表示强制到服务器更新,不走缓存
    
   function f1(){
	   location.assign("http://www.baidu.com");//不能后退,即不产生历史记录
	 // location.href="http://www.baidu.com";
   }
   function f2(){
	   location.replace("http://www.baidu.com");//跟href一样,一个是方法,一个是属性
   }
   //navgator对象
   //alert(navigator);//[object Navigator]
   //浏览器的名称:不过不太准
   //alert(navigator.appName);
   //显示浏览器内核及宿主环境的操作系统等
    //alert(navigator.userAgent);
   //显示的不准,说我的是win32
    //alert(navigator.platform);
   //测试||运算符,当操作的不是布尔值时:当两个都是对象时,返回第一个;第一个是对象,也返回第一个;
   //第一个结果为false,返回第二个
    //这样可以避免变量为undefined或null
    /*
    var a="fsadf";
    var b="unknow";
    alert(a||b);
   */
   /*
    var a={"name":"zhao","age":33};
    alert(a||false);
    */
    //alert((undefined||{"name":"zhao","age":33}).name);//zhao
    //测试对象的属性:用函数给对象增加属性
    /*
    var obj={
    		uname:"输入法",
    		a:function(){
    			this.uname="输入法1";
    		}
    }
    alert(obj.uname);
    obj.a();
    alert(obj.uname);
    */
    /*
    var obj={
    		a:function(){
    			//var uname="222";//肯定都是undefined
    			this.uname="输入法1";//给对象动态增加了属性
    		}
    }
    alert(obj.uname);//undefined
    obj.a();
    alert(obj.uname);//输入法1
    */
    //因此就可以理解浏览器嗅探器了
    /*
    alert(BrowserDetect.browser);
    alert(BrowserDetect.version);
    alert(BrowserDetect.OS);
    */
    
    
	/*
	//问题:一个元素的一个事件只能绑定一个函数
	window.onload=function(){
		alert(1);
	}
	window.onload=function(){
		alert(2);
	}
	window.onload=function(){
		alert(3);
	}
	alert(typeof addEventListener);
	alert(typeof attachEvent);
	window.onload=function(){
		alert(1);
	}
	window.onload=function(){
		alert(2);
	}
	window.onload=function(){
		alert(3);
	}
	*/

	
</script>

四十四、js加载xml实现二级联动

这篇js教程我们分享一个案例:使用javascript读取本地xml并根据xml中的内容实现二级联动,案例就是这么个案例,实现效果如下:

GIF.gif

我们来看看代码是怎么样完成的。

html:

<body>
	<select id="province" name="province" value="fdsf">
		<option value="-1" selected="selected">请选择...</option>
		<option value="hn">河南</option>
		<option value="sd">山东</option>
		<option value="sx">陕西</option>
	</select>
	<select id="city" name="city">
		<option value="-1" selected="selected">请选择...</option>
	</select>
</body>

javascript:

<script type="text/javascript">
//二级联动
window.onload = function() {
	//这里使用下拉框的onchange事件
	var p = document.getElementById("province");
  p.onchange = function() {
		//情况城市下拉框里面原来的东西
	var options=document.getElementById("city").getElementsByTagName("option");
	var len=options.length;
	for(var k=1;k<len;k++){//从第二个开始清除
		//options的长度一直在变
		//数组长度在变,再用下标就会跳过元素,导致不能完全清除	
		document.getElementById("city").removeChild(options[1]);
	}
    //得到选择的省份
	var selectedprovince=this.value;
	//加载xml
	var xmlDoc=parseXML("cities.xml");
	//使用XPath(对xml文档快速定位):得到标签是province并且有name属性并且该属性值是selectedprovince
	var theProvince= xmlDoc.selectNodes("//province[@name='"+selectedprovince+"']")[0];
    var citiesNodeToShow=theProvince.getElementsByTagName("city");//得到选择的省份下面的城市数组
  	 for(var j=0;j<citiesNodeToShow.length;j++){
  		var cityName=citiesNodeToShow[j].firstChild.nodeValue;
  		var optionNode=document.createElement("option");
  		var textNode=document.createTextNode(cityName);
  		optionNode.appendChild(textNode);
  		document.getElementById("city").appendChild(optionNode);
  	 }
  } // p.onchange = function() {
	
	function parseXML(filename){//这里javascript解析xml的方法只适用于ie浏览器
		if(window.ActiveXObject){
			var doc=new ActiveXObject("Microsoft.XMLDOM");
			//设置读取方式
			doc.async="false";
			doc.load(filename);
			return doc;
		}
	}	
}
</script>

cites.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<provinces>
<province name="hn">
	<city>郑州</city>
	<city>开封</city>
	<city>商丘</city>
</province>
<province name="sd">
	<city>济南</city>
	<city>青岛</city>
	<city>烟台</city>
</province>
<province name="sx">
	<city>咸阳</city>
	<city>长安</city>
	<city>汉中</city>
</province>
</provinces>

        

        当然,这些代码都是稳哥n年前写的啦,现在看到代码感觉有点青涩,实现二级联动有个难点,就是上次选择了河南,下次选择其他省份,比如山东的时候,要对与之关联的城市进行清除,要注意代码的写法。另外一点需要注意的就是如何使用javascript读取xml文件,我这里写的parseXML方法只是针对ie,所以你拿这个案例进行测试的时候要使用ie浏览器,不然是没有办法正确工作的,当然javascript在其他浏览器下面也可以读取xml文件,只是代码不同罢了,搞下兼容性即可,我这里表达的是这个意思,回头有机会再写javascript在各个浏览器下兼容读取xml文件吧。

四十五、js模拟java里面的map结构存放键值对

        当然了,随着科技的发展,在es6中,已经渐渐的出现了Map,Set的身影,但是es6虽好,至少截止到目前为止,还有很多浏览器不兼容它,下面的代码是模拟Map键值对结构,一样可以当做Map来用。

<script type="text/javascript">
	function JsMap(){
		var arr=new Array();	
		this.put=function (k,v){
			//对象的格式就是键值对
			arr.push({key:k,value:v});
			//arr.push({k:v});
		}
		this.get=function(k){
			for(var i=0;i<arr.length;i++){
				if(arr[i].key==k){
					return arr[i].value;
				}
			}
			//for(var i=0;i<arr.length;i++){
			//	for(var attr in arr[i]){
			//		if(attr==k) return arr[i][attr];
			//	}
			//}
		}
		this.remove=function(k){
			for(var i=0;i<arr.length;i++){
				if(arr[i].key==k){
					return arr.splice(i, 1);
				}
			}
		}
		this.keys=function(){
			var tmparr=[];
			for(var i=0;i<arr.length;i++){
				tmparr.push(arr[i].key);
			}
			return tmparr;
		}
		this.values=function(){
			var tmparr=[];
			for(var i=0;i<arr.length;i++){
				tmparr.push(arr[i].value);
			}
			return tmparr;
		}
	}
	var map=new JsMap();
	map.put(1, 2);
	map.put(1003, 1003);
	map.put("a", "kfdsa");
	alert(map.values());
</script>

 

四十六、javascript数组去掉重复的元素

<script type="text/javascript">
	var arr=[1,2,3,4,4,6,2];
	var obj={};
	for(var i in arr){
		//对象的属性不会有重复,出现重复的就会把原来的key覆盖掉,
		//注意不是覆盖值哦
		obj[arr[i]]=arr[i];
	}
	var newArr=[];
	for(var attr in obj){
		newArr.push(attr);
	}
	console.log(newArr);
</script>

实现思路:javascript的数组中有重复的元素,那上边的例子来说,4,2都是重复的元素,如何快速高效的找到并去掉重复的数组元素呢?我们可以考虑这样实现:把数组中的元素赋值给一个对象,对象的key是不能重复的,这样就巧妙的实现了快速而高效的数组元素的去重。

四十七、 javascript中==和===的区别

==:比较的是值

===:先值后类型

详细的来说,是这样的:

一、对于string,number等基础类型,==和===是有区别的

1)不同类型间比较,==之比较“转化成同一类型后的值”看“值”是否相等,===如果类型不同,其结果就是不等

2)同类型比较,直接进行“值”比较,两者结果一样 

二、对于Array,Object等高级类型,==和===是没有区别的

当一个变量定义为Arrary和一个变量定义为Object类型时,但是其值相同时,==和===比较的结果是相同的,因为它是进行“指针地址”比较

三、基础类型与高级类型,==和===是有区别的

1)对于==,将高级转化为基础类型,进行“值”比较

2)因为类型不同,===结果为false

四十八、js变量

<script type="text/javascript">
	//js也有变量类型,通过typeof x来看,多出来的一些数据类型只不过是对java异常的封装
	//基本类型:number(NAN,infinity,-infinity),string,boolen,undefine,null
	//引用类型:数组/[],Date等,单体对象(Globle,Math),object/{},Function,RegExp,基本类型的包装类
	var a=parseInt("abcd");//NAN
	var b=1/0;//infinity
	var c;//undefine
	var g=null;
	//声明对象的三种方式
	var d=[1,2];
	var e=new Date();
	var f={};
	//没有弹出null,而是object,这是因为g是空对象的引用
	alert(typeof g);
	function test(){
		//全局变量:不加var,只能在函数调用后
		h=0;
		alert(h);
	}
	//alert("before invoke"+h);
	test();
	alert("after invoke"+h);
</script>

四十九、包装对象、内置对象Gloable和Math和对象和闭包

<script type="text/javascript" >
	//js四舍五入
	/*var num1=19.457;
	alert(num1.toFixed(2));//19.46
	num1=20;
	alert(num1.toFixed(2));//20.00
	alert(typeof num1.toString());
	*/
	//String包装对象
	/*var str=new String("dfsafe");
	alert(typeof str);//object
	str.f1=function(){
		alert("f1");
	}
	str.f1();
	*/
	//帮助生成html
	/*
	var str="百度";
	 str=str.link("http://www.baidu.com");
	alert(str);
	*/
	
	/*
		//gloable的实现:window,实际上没有所谓的全局变量和全局方法,而是属于window对象的
		/* 
		var str="http://zhao.com";
		alert(encodeURI(str));//只会对中文
		alert(encodeURIComponent(str));//编码来的更彻底
		alert(decodeURI(encodeURI(str)));
		alert(decodeURIComponent(encodeURIComponent(str)));
		*/
		//eval把字符串解析成js代码
	/*	
	   var str="var box=100";
		eval(str);
		alert(box);
		eval("alert(103)");
	 */
	 /*
	 function f(){
		 
	 }
		alert(f.prototype);
		*/
		
		//为了解决得到实例时的大量重复工作,可以使用工厂模式。
		/*
		function createObj(un,age){
			var obj=new Object();
			obj.uname=un;
			obj.age=age;
			obj.run=function (){
				return this.uname+"今年"+this.age+"岁了";
			};
			return obj;
		}
		
		var a=createObj("zhao","25");
		var b=createObj("难得很","23");
		alert(a.run());
		alert(typeof a);
		alert(typeof b);
		*/
		//而工厂模式创建出来的对象使用typeof时都是object,不能区别类型,优化后得到了构造函数的方式
		/*
		function Person(uname,age){
			this.uname=uname;
			this.age=age;
			this.run=function(){//相当于new Function(...); 也就是说每次new一个对象,都会创建个函数
				return this.uname+"今年"+this.age+"岁了";
			};
		}
		var p1=new Person("a",33);
		var p2=new Person("b",22);
		alert(p2.run());
		alert(p1.run==p2.run);
		*/
		
		//这种方式会为每个实例对象都分配一个函数(如果有的话),故有原型的方式,原型的方式有个缺点就是
		//属性初始化都一样
		//每一个函数天生就有一个prototype属性
		/*
		function Person(uname,age){
			this.uname=uname;
			this.age=age;
		}
		Person.prototype={
			  run:function(){//只加载一次,new Function()一次
				return this.uname+"今年"+this.age+"岁了";
			 }
		}
		var p1=new Person("a",33);
		var p2=new Person("b",22);
		alert(p2.run());
		alert(p1.run==p2.run);
		*/
	/*	
	   function User(userName,userAge){
			this.userName=userName;
			this.userAge=userAge;
		}
		//prototype是个对象,存放所有对象实例共享的东西
		User.prototype.introduce=function(){
			alert("jinru");
		}
		var u=new User("zhaodw",25);
		//u.introduce();
	*/	
	
	//上面这种方式看起来很不舒服,所以也可以合起来写
	/*function User(userName,userAge){
		this.userName=userName;
		this.userAge=userAge;
		if(typeof this.introduce != "function"){//如果相等,说明原型部分已经加载过了[加载过了,所有实例都会有]
			alert("被应被加载一次(原型的共享性)开始");
			User.prototype.introduce=function(){//不能用prototype={x:a}来声明多个函数,要一个个写
				alert("jinru");
			}
			alert("被应被加载一次(原型的共享性)结束");
		}
	}
	var u=new User("zhaodw",25);
	var u2=new User("zhaodw2",252);
	u2.introduce();
	*/
	
	//闭包:有权访问另一个函数里的变量的函数,使局部变量在闭包未销毁期间驻留内存
	/*
	function f1(){
		var age=100;
		return function (){//闭包
			age++;
			return age;
		}
	}
	var result=f1();//result存放闭包的地址
	alert(result());
	alert(result());//闭包[函数]还未执行完,内部执行环境没销毁,外部也不会销毁,向上检索
	*/
	
	//数组的每个元素都是一个匿名函数,相当于new Function出来的,每次都是一个新的,匿名函数是不会自我执行的
	/*
	function f1(){
		var arr=[];
		for(var i=0;i<10;i++){//i的作用环境执行环境是f1
			 arr[i]=function (){//闭包
				return i;
		    }
		}
		return arr;
	}
	var result=f1();//result是闭包的引用
	for(var i=0;i<result.length;i++){
	//调用的时候会去内存中找i,向上检索得到f1作用域下的i,此时为10,故连续输出10个10
		document.write(result[i]());
		document.write("<br/>");
	}
	*/
	//让闭包自我执行
	/*
	function f1(){
		var arr=[];
		for(var i=0;i<10;i++){//i的作用环境执行环境是f1
			 //注意,每次都是new一个Function再赋给arr的元素的
			 arr[i]=(function (num){ 
				     return num;
		            })(i);
		}
		return arr;
	}
	var result=f1();//result是闭包的引用
	for(var i=0;i<result.length;i++){
	//调用的时候会去内存中找i,向上检索得到f1作用域下的i,此时为10,故连续输出10个10
		//document.write(result[i]());
	//调用的时候会去内存中找i,向上检索得到f1作用域下的i,此时为10,故连续输出10个10	
		document.write(result[i]);
		document.write("<br/>");
	}
	*/
	function f1(){
		var arr=[];
		for(var i=0;i<10;i++){//i的作用环境执行环境是f1
			 //注意,每次都是new一个Function再赋给arr的元素的
		//10个函数的num分别为从0到9,里面自然也有1个[每次也是new的]不同于其他的内部函数	 
			 arr[i]=(function (num){ 
				     //num相当于匿名函数的局部变量,在这里
				     return function (){//new 一个
				    	 return num;
				     }
		            })(i);
		}
		return arr;
	}
	var result=f1();//result是闭包的引用
	for(var i=0;i<result.length;i++){
		//document.write(result[i]());
		//调用的时候会去内存中找i,向上检索得到f1作用域下的i,此时为10,故连续输出10个10
	document.write(result[i]());//调用的时候会去内存中找i,向上检索得到f1作用域下的i,此时为10,故连续输出10个10
		document.write("<br/>");
	}
</script>

 

五十、javascript里面的匿名函数和闭包

<script type="text/javascript" >
	/*
		//把函数封装成表达式执行,多用于匿名函数
		alert((function f1(){
			return "zhaofd";
		})());	
		//(匿名函数)():自我执行
		(function (){
			alert("fdsfe");
		})();
		//一个函数f1可以访问另一个函数f2的局部变量,f1在f2中,f1可访问所有的上级的局部变量(
		//每个函数执行后都有个scope域	)
		
		//闭包可以使能访问的scope里的变量长期驻留内存,因为外部引用了闭包,或者说有闭包的引用,闭包的
		//作用域或者叫执行环境不得销毁,它的外部环境自然也不能被销毁,就达到了驻留内存的效果
		//通过闭包在外部操作局部变量
		function f1(){
			var a=100;
			return function(){
				a++;
				return a;
			}		
		}
		//b就是闭包,匿名函数
		var b=f1();
		alert(b());//101
		alert(b());//102
		
		  //循环里匿名函数的取值问题
	      function f1(){
			var arr=[];
			for(var i=0;i<5;i++){
				arr[i]= function(){
					//i是f1 scope里的局部变量,当在外部f1() 时,返回arr,arr里的每个元素
					//都是function (){return i}.arr[0]()的值是return 的i,此时的i经过循环
					//后是5了,所以数组里弹出的都是5
					return i;
				};
			}
			return arr;
		  }
			for(var k=0;k<5;k++){
		    	alert(f1()[k]());
			}
			
			 //解决循环里匿名函数的取值问题-1
		    function f1(){
				var arr=[];
				for(var i=0;i<5;i++){
					arr[i]= (function(){
						return i;
					})();//通过匿名函数的即时执行,把循环时的i就赋给数组元素
				}
				return arr;
			  }
				for(var k=0;k<5;k++){
			    	alert(f1()[k]);//注意此时返回的不是函数了
				}		
				 //解决循环里匿名函数的取值问题-2
			    function f1(){
					var arr=[];
					for(var i=0;i<5;i++){
						arr[i]= (function(num){
							return num;
						})(i);//通过匿名函数的及时执行,把循环时的i就赋给数组元素
					}
					return arr;
				  }
					for(var k=0;k<5;k++){
				    	alert(f1()[k]);//注意此时返回的不是函数了
					}		
					
	 //解决循环里匿名函数的取值问题-3
	 //理解:每一个函数被调用后都会有一个自己的scope,这个scope包含了所有的该函数执行的
	 //上下文信息,不仅指向自己的scope,上级的也会被指向。被调用一次,就开辟一次(重新开辟)
	 //function(num){return function(){return num;}}每次自调用时,都会开辟自己的一个scope,
	 //共开辟了5个,这个函数的一个scope里面指向:本身的scope(有num和no匿名函数)和f1的scope和gloable scope
    function f1(){
		var arr=[];
		for(var i=0;i<5;i++){
			arr[i]= (function(num){
				return function(){
					return num;
				}
			})(i);
		}
		return arr;
	  }
		for(var k=0;k<5;k++){
	    	alert(f1()[k]);
		}		
	*/	
    function compareObject(prop){
		return function (obj1,obj2){
			alert(prop);
			if(obj1[prop]>obj2[prop]) return 1;
			if(obj1[prop]<obj2[prop]) return -1;
			if(obj1[prop]=obj2[prop]) return 0;
		}
	  }
		var o1={n:"leee",age:22};				
		var o2={n:"abc",age:25};				
		var func=compareObject("n");
		var func=compareObject("age");
		var res=func(o1,o2);
		alert(res);
</script>

 

五十一、js中的files对象

js中的files对象用来获取type="file"的表单元素上传的文件信息,可以获取的信息包括文件的类型、大小、名字等。下面是一个使用示例:

html代码:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script src="jquery-1.10.2.js"></script>
</head>
<body>
    <input type="file" name="" id="fileId" onchange="upload()">
</body>
</html>

javascript代码:

<script>
var filePath ="";
var fileType ="";
function upload(){
	var inputVal=$('#fileId').val();
	console.log("输入框的值:"+inputVal);//C:\fakepath\新建文本文档.txt
    var arr = inputVal.split('\\'); //得到文件名数组,输出结果:["C:", "fakepath", "新建文本文档.txt"]
	var fileName = arr[arr.length-1]; // 获得文件名,比如:新建文本文档.txt
    var filePath = inputVal.toLowerCase().split(".");
	console.log(filePath);
    var fileType =  filePath[filePath.length - 1]; //获得文件结尾的类型如 zip rar 这种写法确保是最后的
    console.log(fileType);
	//<input type="file" name="" id="fileId" onchange="upload()" multiple> 其中multiple可以让你上传多个文件
	console.log("$('#fileId')[0].files:"+$('#fileId')[0].files);//[object FileList]
	//获得上传的文件信息;
    var fileInfo =  $('#fileId')[0].files[0]; 
	/*
	File(3394) {name: "lzz_crawl.sql", lastModified: 1531627162766, lastModifiedDate: Sun Jul 15 2018 
	11:59:22 GMT+0800 (中国标准时间), webkitRelativePath: "", size: 3394,type:""}
	*/
	console.log(fileInfo);
    if(!(fileType == "png" || fileType == "jpg" || fileType == "xlsx"|| 
	   fileType == "docx"|| fileType == "rar" || fileType == "zip" )){
        alert('文件格式不符合要求!');
    }else if(fileInfo.size>10485760){
        alert('错误!请上传不超过10M的文件');
        return;
    }else{
		//上传就行了
	}
}
</script>

在浏览器上上传一个文件,输出的信息截图如下:

image.png

通过获取type="file"的表单元素的val()以及files对象的文件信息我们可以做文件类型,文件大小的判断。

五十二、javascript FileReader对象

javascript里面的File API,被IE10+,Firefox3.5+,Opera10.6+,Safari5+,Chrome浏览器支持。

01.在表单元素上<input type="file" name="file" id="file" />,可以选择一个或多个文件,通过获取文件元素对象的集合files,来操作每一个对象files[i];

用法示例:  

var files=document.getElementById("file");
  var file=files.files;//每一个file对象对应一个文件。
  file.name//获取本地文件系统的文件名。
  file.size//文件的字节大小。
  file.type//字符串类型,文件的MIME类型。
  file.lastModifiedDate//文件的最后修改时间。(只使用于Chrome浏览器)

 

02.通过FileReader类型读取文件中的数据(异步文件读取)

FileReader有一下几种读取文件数据的方法

1).readAsText(file,encoding);以纯文本的形式读取文件,将读取到的文件保存到result属性。encoding参数用于指定编码类型,是可选的。

2).readAsDataURL(file);读取文件并将文件数据以URL形式保存到result属性中。(读取图像文件常用方法)

3).readAsBinaryString(file);读取文件并将一个字符串保存在result属性中,字符串中的每个字符表示一字节。

4).readAsArrayBuffer(file);读取文件并将一个包含文件内容的ArrayBuffer保存在result属性中。

判断浏览器是否支持FileReader对象:

if(window.FileReader) {
     var fr = new FileReader();
     // add your code here
 }
 else {
     alert("Not supported by your browser!");
 }

03.FileReader提供了几个事件最有用的三个事件,progress,error,load,分别表示是否又读取了新数据,是否发生了错误,是否已经读完整个文件。

FileReader 包含了一套完整的事件模型,用于捕获读取文件时的状态,下面这个表格归纳了这些事件。

事件

描述

onabort

中断时触发

onerror

出错时触发

onload

文件读取成功完成时触发

onloadend

读取完成触发,无论成功或失败

onloadstart

读取开始时触发

onprogress

读取中

文件一旦开始读取,无论成功或失败,实例的 result 属性都会被填充。如果读取失败,则 result 的值为 null ,否则即是读取的结果,绝大多数的程序都会在成功读取文件的时候,抓取这个值。

用法举例:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>FileReader</title>
</head>
<body>
    <p> 
    <label>请选择一个文件:</label> 
        <input type="file" id="file" /> 
        <input type="button" value="读取图像" onclick="readAsDataURL()" /> 
        <input type="button" value="读取二进制数据" onclick="readAsBinaryString()" /> 
        <input type="button" value="读取文本文件" onclick="readAsText()" /> 
    </p> 
    <div id="result" name="result"></div> 


<script type="text/javascript"> 
var result=document.getElementById("result"); 
var file=document.getElementById("file"); 
//判断浏览器是否支持FileReader接口 
if(typeof FileReader == 'undefined'){ 
    result.InnerHTML="<p>你的浏览器不支持FileReader接口!</p>"; 
    //使选择控件不可操作 
    file.setAttribute("disabled","disabled"); 
} 

function readAsDataURL(){ 
    //检验是否为图像文件 
    var file = document.getElementById("file").files[0]; 
    if(!/image\/\w+/.test(file.type)){ 
        alert("看清楚,这个需要图片!"); 
        return false; 
    } 
    var reader = new FileReader(); 
    //将文件以Data URL形式读入页面 
    reader.readAsDataURL(file); 
    reader.onload=function(e){ 
        var result=document.getElementById("result"); 
        //显示文件 
        result.innerHTML='<img src="' + this.result +'" alt="" />'; 
    } 
} 

function readAsBinaryString(){ 
    var file = document.getElementById("file").files[0]; 
    var reader = new FileReader(); 
    //将文件以二进制形式读入页面 
    reader.readAsBinaryString(file); 
    reader.onload=function(f){ 
        var result=document.getElementById("result"); 
        //显示文件 
        result.innerHTML=this.result; 
    } 
} 

function readAsText(){ 
    var file = document.getElementById("file").files[0]; 
    var reader = new FileReader(); 
    //将文件以文本形式读入页面 
    reader.readAsText(file); 
    reader.onload=function(f){ 
        var result=document.getElementById("result"); 
        //显示文件 
        result.innerHTML=this.result; 
    } 
} 

</script> 

</body>
</html>

需求:使用js的FileReader对象实现上传图片时的图片预览功能

<!DOCTYPE html>
<html>
   <head>
   <meta  name="viewport"  content="width=device-width,initial-scale=1, user-scalable=no">
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
   <meta name="format-detection" content="telephone=no">
   <title>test</title>
   <script>
    //选择图片时预览功能
    function imageshow(source){
                   var file = source.files[0];
                   var imageid = source.id;
                   if (window.FileReader) {
                       var fr = new FileReader();
                       fr.onloadend = function(e) {
                          document.getElementById("portrait"+imageid).src = e.target.result;
                       };
                       fr.readAsDataURL(file);
                  }
    document.getElementById("image"+imageid).style.display="none";
       document.getElementById("show"+imageid).style.display="block";
      }
  </script>
  </head>
<body>
<div>
      <div id="image1" >
      <p>上传截图</p>
          <input type="file" name="screenshot1" id="1" onchange="imageshow(this)"/>
      </div>
    <div id="show1" style="display:none;">
      <img  src="" id="portrait1" width="100" height="70">
    </div>
    <div id="image2">
          <p>上传截图</p>
          <input type="file" name="screenshot2" id="2" onchange="imageshow(this)"/>
      </div>
    <div id="show2" style="display:none;">
      <img  src="" id="portrait2" width="100" height="70">
   </div>
         <div id="image3">
            <p>上传截图</p>
            <input type="file" name="screenshot3" id="3" onchange="imageshow(this)"/>
         </div>
      <div id="show3" style="display:none;">
      <img  src="" id="portrait3" width="100" height="70" >
    </div>
</div> 
</body>
</html>

五十三、location对象的pathname的应用场景

location对象是BOM内置对象之一,主要用于返回或者设置地址栏的信息。比如:

console.log(location.pathname+","+location.search+","+location.hash)

假如浏览器地址栏的访问地址为:http://localhost:8080/lzz-services/toRechargeManageUser?q=www.tmp#high

那么输出值为:/lzz-services/toRechargeManageUser,?q=www.tmp,#high

location属性解释:

hash:设置或返回从井号 (#) 开始的 URL(锚)。

pathname:设置或返回当前 URL 的路径部分。

search:设置或返回从问号 (?) 开始的 URL(查询部分)。

应用场景:

        比如有个侧边栏导航,如下:

image.png

当点击"新建规则"的时候跳转到新的url,假如说是http://localhost:8080/fraud/addRule,因为侧边栏是所有页面共享的公共页面,如何使得跳转过去之后正好让这个新建规则高亮呢?这时候就可以通过location对象获取到当前地址栏的地址并与左侧菜单栏的所有地址相比较,如果相等就高亮,即可实现选中相应菜单。

五十四、document.referrer的用法

假设有个test.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>document.referrer</title>
</head>
<body>
<script>
document.write(document.referrer);
</script>
</body>
</html>

访问路径是"http://localhost:8080/d3/test.html",当直接在浏览器地址栏输入这个地址时,页面无输出。

另有一个index.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>document.referrer</title>
</head>
<body>
   <a target="_blank" href="test.html?from=index">test.html</a>
 </body>  
</html>

当通过index.html的超链接访问test.html的时候,test.html页面才有输出:

image.png

即:

    ①:document.referrer 属性可返回载入当前文档的文档的 URL。

    ②:如果当前文档不是通过超级链接访问的,则为 null。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值