本书的JS
1.1 执行js代码
javascript:alert(‘执行js’);//一般放在超链接中,用户点击即执行,
1.2 变量赋值
- var a = 1;//显式
- a =1; //隐式
1.3 全局变量与局部变量
- ...
- var scope = "全局变量";
- function test() {
- alert(scope); // undefiend
- var scope = "局部变量";
- alert(scope); // 局部变量
- }
因为全局变量被局部变量覆盖了.虽然局部变量的scope还没赋值,但是已经在方法里”占”上位置了.
但如果把局部变量的var删了,就会先输出全局变量后输出局部变量,因为没有var在方法里给局部变量”占”位置;
1.4 浮点数
- var a = .333
- var b = a * 5;
- alert(b);
得出的结果是 1.66499999999999999
所以在js中判断浮点数是否相等 建议判断两者的差值是否小于一个足够的数(例如0.0000000000001)
1.5 字符串
js中没有字符类型变量 “”与’‘一致
- var s = "abcdefg"
- //b = "def"
- b = s.slice(3, -1);
1.6 字符串的正则表达式方法中
1.7 undefined和null
- null == undefined //true
- null === undefined //false
undefined 是没设值
null则是设定了为null值
1.8 运算符
- //逗号运算符 取最右返回值
- a = (b = 5, c = 7, d = 56) //a =56
- a = void(b = 5, c = 7, d = 56) //a = undefined
1.9 typeof和instanceof
typeof 用来获得 实例类型 :
- typeof("123"); //string
instanceof 判断变量是否为某类的实例
- var a = [4,5];
- alert(a instanceof Array); //true
1.10 语句
抛出异常
- throw new Error("用户自定义异常"); //一般用于终止程序和返回错误提示是个不错的选择;
- try{
- }catch(e){
- alert(e.message); // "用户自定义异常"
- }
for in
- //这回输出浏览器的所有属性,做浏览器兼容之前可以考虑看看.
- for (prop_name in navigator) {
- document.wrti(prop_name + " : " + navigator[propname]);
- }
跳出命名for
- outer:
- for(...){
- for(...){
- ...
- continue outer;
- }
- }
1.11 函数
js 允许先调用函数 再定义函数
1.11.1 定义匿名函数
- var show_name = function(name){
- alert(name);
- }
- show_name("K"); //K
这样的好处是什么,如果直接定义function 它实际上也是创建了一个对象
1.11.2 函数既对象
- var hello = function() {...
- };
- hello instanceof Function //true;
- hello instanceof Object //true;
- alert(heelo) //输出函数源代码
【我有一个前端学习交流QQ群:328058344 如果你在学习前端的过程中遇到什么问题,欢迎来我的QQ群提问,群里每天还会更新一些学习资源。禁止闲聊,非喜勿进。】
1.11.3 调用函数方式的不同
1.11.4 this关键字.
- var hello =function(){...}
- window.hello();
- var p = {
- wark: function(){...}
- }
- p.wark();
1.11.5 函数中的变量有三种
- function Person() {
- //局部变量 只能在函数里访问
- var id;
- //实例属性 通过对象.访问
- this.age;
- //类属性 通过Patient.name访问 与static类似
- Person.name;
- }
1.11.6 js是一种动态语言,能随时给对象增加属性和方法
- function Student() {};
- var student = new Student();
- //动态增加name属性
- student.name = 'K';
- alert(sutdent.name) //K
- Student.age = 22;
- alert(Student.age); //22 类属性也是可以动态添加的
1.11.7 调用函数的三种方式
- windows.alert();
- //or
- alert();
- var each = function(array, fn) {
- for (var index in arrary) {
- //null表示以window为调用者fn函数
- fn.call(null, index, arrary[index]);
- }
- }
- each([4, 20, 3],
- function(index, ele) {
- alert("第 " + index "个元素是 : " + ele);
- });
call()调用函数语法为:
直接调用函数语法为:
- 函数引用.call(调用者,参数1,参数2...)
- 调用者.函数(参数1,参数2 ...) = 函数.call(调用者,参数1,参数2 ...)
- var myfun = function(a, b) {
- alert(a + " " + b);
- }
- myfun.call(window, 12, 23); //12 23;
- myfun.apply(window, [20, 39]); //20 39
- var example = function(num1, num2) {
- //直接调用arguments代表调用者(example,this代表example)时的传入的所有参数
- myfun.apply(this, arguments);
- }
- example(20, 40) //20 40
1.11.8 函数的独立性
在函数A中可以定义函数B,但是函数B还是独立于函数A
- function Person(name) {
- this.name = name;
- this.info = function() {
- alert(this.name);
- }
- }
- var person = new Person('K');
- person.info(); //K
- var name = 'K_window';
- //由于window为调用者 ,this.name访问的是window.name
- p.info.call(window); //K_window
来爽一发猫学狗叫?.
- function Dog(name, bark) {
- this.name = name;
- this.bark = bark;
- this.info = function() {
- alert(this.name + " " + this.bark);
- }
- }
- function Cat(name) {
- this.name = name;
- }
- var dog = new Dog("K", "汪汪!");
- var cat = new Cat("K_2");
- dog.info.call(cat); //K_2 undefined
1.11.9 参数传递方式
和JAVA一样 都是值传递拉~.
基本类型
- function change(arg){
- arg =10 ;
- alert(arg);
- }
- var x = 5;
- alert(x); //5
- change(x); //10
- alert(x); //5
复合类型
- function change(person){
- person.age = 10;
- alert(person.age);
- person = null;
- }
- var person = {age : 5};
- alert(person.age); //5
- change(person); //10
- alert(person.age); // 10
- alert(person); // []object Object]
复合类型的传递为值传递,原person和参数person指向同一javascript对象,所以当改变age的时候,是在改变javascript对象的age,但是参数person赋值为null,原person并无改变.
1.11.10 空参数
- function text(person){
- alert( typeof parson);
- }
- text(); //undefined
所以对于弱类型,方法重载是无作用的,因为js会把空参数当做undefined传递进去;
同名函数,后面出现的会覆盖前面的,无论参数个数是多少.
1.11.11 对象和关联数组
javascript和Map有点类似,当key为对象,value为函数,该该函数就是对象的方法,当key为对象,value为基本类型,则该基本类型为对象的属性.(以上为便于理解,切勿细琢)所以访问属性时,可以obj.propName也可以obj[propName].
但有时候我们只能用obj[propName],因为.propName不能把propName当做变量处理,而是把他当成’propName’字符串
- function Person(name) {
- this.name = name;
- this.info = function() {
- alert(K);
- }
- }
- var person = new Person("K");
- //遍历person属性
- for (propName in person) {
- alert(p[propName]); //alet K info源代码 假如此处用p.propName则undefined,因为Person无'propName'变量.
- }
1.11.12 继承和prototype
在一个类(函数)中定义一个函数会导致
- function Person() {
- var local = "局部变量"this.info = function() {
- //产生闭包
- alert(local);
- }
- }
- var person = new Person();
- person.ifno(); // 局部变量
解决方案:prototype
增加了prototype属性的类可视为继承了原先的类(伪继承)
- function Person(){...}
- var person = new Person();
- //person.wark(); 程序报错wark不存在
- Person.prototype.wark = function(){...}
- person.wark(); //ok
在prototype之前实例化的类会具有wark方法吗? 有的,因为prototype这样并不会产生一个新的类,而是直接动态的往Person里加函数.
判断某方法是否继承了该对象
- 该对象.prototype['某方法'] != undefined;
- var test = new该对象 ();
- test.某方法 != undefined;
1.12 创建对象三种方式
//(单身汪别说我不教你)
- function Person(name){...}
- var person_1 = new Person();
- var person_2 = new Person('K'); //js不存在方法重载,空参数undefined顶替
- var my_obj = new Object();
- my_ojb.name = 'K';
- my_obj.handsome = function(){...}
- function text(){...}
- my_obj.text = text;//不要添加(),不然会认为是调用方法
- ver person = {
- name: 'K',
- school: ['ChangAn', 'TianJin'],
- girl_friends: [{
- name: 'Haski',
- age: 11
- },
- {
- name: 'Samoyed',
- age: '8'
- }]
- }
- alert(person.girl_friends[0].name); //Haski
DOM操作其实JQuery已经做得很好了,这里简单补充一下原生JS的知识
HTML文档中只有一个根节点
2.1 访问HTML元素
- Node parentNode: 返回父节点
- Node previousSibling: 返回前一个兄弟节点
- Node nextSibling: 饭后后一个兄弟节点
- Node[] childNodes 返回当前节点的所有节点
- Node[] getElementsByTagName('标签名称'): 返回当前节点具有制定标签的子节点
- //注意ol标签的子标签IE8和其他浏览器不一样(其他浏览器会把ol下的li和其后面的空白分别当成2个节点,IE8则不会)
2.2 增加HTML函数
2.3 添加节点
2.4 删除节点
2.5 window对象
- for (var propName in window.screen) {
- alert(propName + ":" + screent[propname]);
- }
- var timer;
- var cur = new Date().getTime();
- var setTime = function() {
- document.getElementById("tm").innerHTML = new Date().toLocationString();
- if (new Date().getTime - cur > 60 * 1000) {
- clearInterval(timer);
- }
- }
- //每1S执行一次,执行了60次就暂停
- timer = window.setInterval("setTime()", 1000);
2.6 navigator和地理位置
navigator汉堡浏览器所有信息,遍历循环获取信息
- for (var propName in window.navigator) {
- alert(propName + ":" + window.navigator[propName]);
- }
HTML5新增geolocation属性
Geolocation提供的方法
上面的前两个方法的options参数是一个对象,可包含3个变量
- var geoHandler = function(position){
- var geoMsg = "用户地址位置是 : <br/>"
- geoMsg += "timestamp属性为 :" + position.timestamp + "<br/>"//获取位置的时间
- var cords =position.coords;
- for(var prop in coords ){
- geoMsg += prop + ": " + coords[prop] +"<br/>"//经纬度,移动速度等
- }
- document.writeln(geoMsg);
- }
- var errorHandler = function(error){
- var errMsg = {
- 1: '用户拒绝了位置服务'
- 2: '无法获取地址位置信息'
- 3: '获取地理位置信息超时'
- };
- alert(error[error.code]);
- }
- navigator.geolocation.getCurrentPosition(geoHandler
- , errorHandler
- , {
- enableHighAccuracy:true,
- maximuAge:1000
- });
【我有一个前端学习交流QQ群:328058344 如果你在学习前端的过程中遇到什么问题,欢迎来我的QQ群提问,群里每天还会更新一些学习资源。禁止闲聊,非喜勿进。】
2.7 HTML5新增浏览器分析
实现该功能主要通过performance对象
其中的(PerformanceTiming)timing属性包含加载时间相关的属性
另外(PerformanceNavigation)navigation,主要属性有
type :
- TYPE_NAVIGATE(数值为0): 超链接/输入url
- TYPE_RELOAD(1): 重新加载方式,diaoyonglocation.reload()等
- TYPE_BACK_FORWARD(2): 通过浏览器的前进方式
- TYPE_RESERVED(255): 未知方式
3 事件处理机制
3.1 常见事件
3.2 事件处理和this
- p.info = function(){
- alert(this.name);
- }
- document.getElementById("bt").onclick = p.info//this指向'bt'控件
- document.getElementById("bt").onclick = new function (){ p.info();} //this总是指向p
注意表单设置id为x和name为y时候,相当于表单创建了x属性和y属性,所以id和name不能是关键字submit等
3.3 DOM
创建监听事件
objectTarget.addEventListener(“eventType”,handler,capture),第一个参数表示绑定的事件,如click、keypress之类的,第二个制定绑定的函数,第3个位boolean,true表示监听捕获阶段,false表示监听冒泡阶段
objectTarget.removeEventListener(“eventType”,handler,captureFlag): 删除绑定事件
捕获状态阶段的绑定事件先执行,事件冒泡状态阶段的绑定事件后执行. 捕获状态阶段从外往内触发,事件冒泡状态阶段从内往外触发.
绑定例子
- var got_click = function(event) {
- for (event_one in event) {
- alert(event_one + " : " + event[event_one]);
- }
- }
- document.getElementByID("test").addEventListener("cilck", got_click, true);
阻止事件传播
- event.stopPropagation();
取消事件的默认行为,如跳转页面等,但不会阻止事件传播.
- event.preventDefault();
3.3.1转发事件
DOM提供了dispathEvent方法用于事件转发,该方法属于Node
target.dispathEvent(Event event),将event转发到target上
DOM的dispath()必须转发人工合成的Event事件
document.createEvent(String type),tpy参数用于指定事件类型,eg:普通事件Events,UI事件UIEvents,鼠标事件:MouseEvents
初始化事件
- initEvent(具体参数...)
- initUIEvent(具体参数...)
- intMouseEvent(具体参数...)
- //例子
- <input id="bt1">
- <input id="bt2">
- ...
- var rd =function(evt){
- alert("事件冒泡阶段: " + evt.currentTarget.value +"被点击了");
- var e =document.createEvent("Evnets");
- e.initEvent("click",true,false);//true表示是否支持冒泡,false表示是否有默认行为
- document.getElementById("bn2").dispathEvent(e);
- }
- var go_click = function (evt){
- alert("事件冒泡阶段: " + evt.currentTarget.value);
- }
- document.getElementById("bn1").addEventListener("click",rd,false);
- document.getElementById("bn2").addEventListener("click",go_click,false);;
- //点解按钮一结果
- alert(事件冒泡阶段: 按钮一被点击了);
- alert(事件冒泡阶段:按钮2);
点击按钮1,按钮执行了前面按钮一被点击了提示语句后,将点击事件转给了按钮2,按钮2执行自身的点击事件.
4.1 Web Storage
使用理由之一Cookie的局限性:
Web Storage包含在window对象中
当value为对象时,建议用JSON存储
4.2 构建离线应用
- //表明该页使用index.manifest文件
- < html manifest = "index.manifest" >
- CACHE MANIFEST
- //第一行必须为上述字符
- //指定版本号
- #version 1
- //本地缓存资源
- CACHE
- inedx.html
- logo.jpg
- //不缓存的资源
- NETWORK
- *
- //前者表示在线状态使用的资源,后者代表离线状态使用的资源
- FALLBACK
- test.js offline.js
- <!--conf的web.xml根元素中增加MIME映射-->
- <mine-mapping>
- <extension>manifest</extension>
- <mine-type>text/cache-mainfest</mime-type>
- </mime-mapping>
启动应用后,页面可刷新(即使离线状态),并使用离线时候的资源
4.2.1 判断在线状态
navigator.onLine属性: true表示在线
online/offline事件: 当在线/离线状态切换时,body上的online/offine事件会被触发,沿着document.body、document和window冒泡
- window.addEventListener("offline",function(){
- alert("离线状态")
- },true);
- if(navigator.onLine){
- alert("在线");
- }
4.2.2 applicationCache对象
js可通过applicationCache控制离线缓存.
status属性:
常用方法
- setInterval(function() {
- applicationCache.update()
- },
- 2000);
- applicationCache.onupdateready = function() {
- if (confirm("已从远程服务器下载了需要的缓存,是否更新?")) {
- applicationCache.swapCache();
- location.reload();
- }
- }
4.2.3 离线应用的事件与监听
访问html页面过程
当用户再访问index.html时,前面1~5完全相同,接下来检测mainfest文件是否有改变.
worker中无法使用DOM、alert等与界面有关的操作.
使用理由:防止js阻塞主线程的js运行
WorkerAPI
- onmessage = function(event) {
- var data = JSON.parse(event.data);
- var start = data.start;
- var end = data.end;
- var result = "";
- search: for (var n = start; n <= end: n++) {
- if (n % i == 0) {
- continue search;
- }
- result += (n + ",");
- }
- }
- postMessage(result);
网页代码
- <input name="start" ...>
- <input name="end" ...>
- <input type=button inclick="cal();" ...>
- ...
- var car =function(){
- var start = parseInt(document.getElementById("start").value);
- var end = parseInt(document.getElementById("end").value);
- //创建线程
- var cal = new Worker("worker.js");
- var data ={
- "start" : srart,
- "end" : end
- };
- //发送数据
- cal.postMessage(JSON.stringify(data));
- cal.onmessage = function (evnet){
- alert(event);
- }
- }
并行的两条Worker不能互相通信,但Wroker可嵌套.
WebSocket: 服务器主动推送信息/客户端实时推送数据到服务器
6.1 跨文档通信
window对象新增方法
html想发送要做
html想接收要做
- //source.html
- var targetWin = window.open("接收方url", '_blank', 'windth=400,height=300');
- targetWin.onload = function() {
- targetWin.postMessage("传输消息", "接收方域名");
- }
- window.onmessage = function(event) {
- //忽略其他域名发送的消息
- if (event.orgin != "指定域名") {
- return;
- }
- alert(event.data);
- }
- //接收页面.html
- window.onmessage = function(event) {
- //忽略其他域名发送的消息
- if (event.orgin != "指定域名") {
- return;
- }
- alert("接收到消息拉!" + event.data);
- event.source.postMessage("回传消息", event.origin);
- }
结果:
alert(接收到消息拉!传输消息);
alert(回传消息);
注意!一定要判断发送方的域名!!!!!一定要判断发送方的域名!!!!!一定要判断发送方的域名!!!!!
以前方案:
WebSocket方法
WebSocket监听事件
WebSocket属性
WebSocket与服务器通信步骤
客户端代码:
- var web_socket = new WebSocket("ws://域名:端口");
- web_socket.onopen = function() {
- web_socket.onmessage = function(event) {
- document.getElementById('show').innerHTML += event.data + "</br>"
- }
- };
- var sendMsg = function(val) {
- var inputElement = document.getElementByID('msg');
- webSocket.send(inputElement.value);
- inputElement.value = "";
- }
- ...
服务端代码
- <article class="post" style="margin: 0px; padding: 30px 0px; border-bottom: 1px solid rgb(221, 221, 221); border-top: 1px solid rgb(255, 255, 255); position: relative; color: rgb(102, 102, 102); font-family: HelveticaNeue-Light, "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 300; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(238, 238, 238);">
- import java.io.*;
- import java.net.*;
- import java.nio.charset.Charset;
- import java.security.MessageDigest;
- import java.util.regex.*;
- import java.util.*;
- import sun.misc.BASE64Encoder;
- public class ChatServer
- {
- // 记录所有的客户端Soccket
- public static List<Socket> clientSockets
- = new ArrayList<Socket>();
- public ChatServer()throws IOException
- {
- // 创建ServerSocket,准备接受客户端连接
- ServerSocket ss = new ServerSocket(30000);
- while(true)
- {
- // 接收到客户端连接
- Socket socket = ss.accept();
- // 将客户端Socket添加到clientSockets集合中
- clientSockets.add(socket);
- // 启动线程
- new ServerThread(socket).start();
- }
- }
- public static void main(String[] args)
- throws Exception{
- new ChatServer();
- }
- }
- class ServerThread extends Thread
- {
- private Socket socket;
- public ServerThread(Socket socket)
- {
- this.socket = socket;
- }
- public void run()
- {
- try
- {
- // 得到Socket对应的输入流
- InputStream in = socket.getInputStream();
- // 得到Socket对应的输出流
- OutputStream out = socket.getOutputStream();
- byte[] buff = new byte[1024];
- String req = "";
- // 读取数据,此时建立与WebSocket的"握手"。
- int count = in.read(buff);
- // 如果读取的数据长度大于0
- if(count > 0)
- {
- // 将读取的数据转化为字符串
- req = new String(buff , 0 , count);
- System.out.println("握手请求:" + req);
- // 获取WebSocket的key
- String secKey = getSecWebSocketKey(req);
- System.out.println("secKey = " + secKey);
- String response = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: "
- + "websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "
- + getSecWebSocketAccept(secKey) + "\r\n\r\n";
- System.out.println("secAccept = " + getSecWebSocketAccept(secKey));
- out.write(response.getBytes());
- }
- int hasRead = 0;
- // 不断读取WebSocket发送过来的数据
- while((hasRead = in.read(buff)) > 0){
- System.out.println("接收的字节数:" + hasRead);
- /*
- 因为WebSocket发送过来的数据遵循了一定的协议格式,
- 其中第3个〜第6个字节是数据掩码。
- 从第7个字节开始才是真正的有效数据。
- 因此程序使用第3个〜第6个字节对后面的数据进行了处理
- */
- for (int i = 0 ; i < hasRead - 6 ; i++ ){
- buff[i + 6] = (byte) (buff[i % 4 + 2] ^ buff[i + 6]);
- }
- // 获得从浏览器发送过来的数据
- String pushMsg = new String(buff
- , 6 , hasRead - 6 , "UTF-8");
- // 遍历Socket集合,依次向每个Socket发送数据
- for (Iterator<Socket> it = ChatServer.clientSockets.iterator()
- ; it.hasNext() ;)
- {
- try
- {
- Socket s = it.next();
- // 发送数据时,第一个字节必须与读到的第一个字节相同
- byte[] pushHead = new byte[2];
- pushHead[0] = buff[0];
- // 发送数据时,第二个字节记录发送数据的长度
- pushHead[1] = (byte) pushMsg.getBytes("UTF-8").length;
- // 发送前两个字节
- s.getOutputStream().write(pushHead);
- // 发送有效数据
- s.getOutputStream().write(pushMsg.getBytes("UTF-8"));
- }
- catch (SocketException ex)
- {
- // 如果捕捉到异常,表明该Socket已经关闭
- // 将该Socket从Socket集合中删除
- it.remove();
- }
- }
- }
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- finally
- {
- try
- {
- // 关闭Socket
- socket.close();
- }
- catch (IOException ex)
- {
- ex.printStackTrace();
- }
- }
- }
- // 获取WebSocket请求的SecKey
- private String getSecWebSocketKey(String req)
- {
- //构建正则表达式,获取Sec-WebSocket-Key: 后面的内容
- Pattern p = Pattern.compile("^(Sec-WebSocket-Key:).+",
- Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
- Matcher m = p.matcher(req);
- if (m.find())
- {
- // 提取Sec-WebSocket-Key
- String foundstring = m.group();
- return foundstring.split(":")[1].trim();
- }
- else
- {
- return null;
- }
- }
- // 根据WebSocket请求的SecKey计算SecAccept
- private String getSecWebSocketAccept(String key)
- throws Exception
- {
- String guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
- key += guid;
- MessageDigest md = MessageDigest.getInstance("SHA-1");
- md.update(key.getBytes("ISO-8859-1") , 0 , key.length());
- byte[] sha1Hash = md.digest();
- BASE64Encoder encoder = new BASE64Encoder();
- return encoder.encode(sha1Hash);
- }
- }
- [javascript](http://mzkmzk.github.io/blog/categories/javascript/)
- </article>
- <a class="addthis_button_facebook_like" fb:like:layout="button_count" style="margin: 0px; padding: 0px; text-decoration: none; outline-width: 0px; color: rgb(37, 143, 184);"></a><a class="addthis_button_tweet" style="margin: 0px; padding: 0px; text-decoration: none; outline-width: 0px; color: rgb(37, 143, 184);"></a>
【我有一个前端学习交流QQ群:328058344 如果你在学习前端的过程中遇到什么问题,欢迎来我的QQ群提问,群里每天还会更新一些学习资源。禁止闲聊,非喜勿进。】
来源: http://blog.csdn.net/s8233389shaiyuq/article/details/78560882