JS高级程序设计2

面向对象 ,基本模式、对象字面量模式、工厂模式、构造函数模式、原型模式、组合构造函数和原型模式、其余模式见电子书:动态原型模式、寄生构造函数模式(不推荐)、稳妥构造函数模式(要求安全的环境,不使用new 和 this)javascript

//面向对象
/* 【 数据属性】
*  configurable  true 经过 delete删除属性来修改属性
*  enumberable  true  经过 for-in 返回属性
*  writable true 修改属性值
*  value 数据值
*  es5 经过 Object.defineProperty(obj,属性名,对象{} ) 可对以上修改
*  属性名为 configurable/enumerable/writable/value
*  把 configurable 设置为 false后,就没法再设置为true 了,
*  调用 Object.defineProperty() 默认属性名都为 false
* */
var person = {}
Object.defineProperty(person,"name",{
  writable: false,  // 阻止修改属性值
  value:'xiaoming'
})
console.log(person.name)
person.name = 'xxx';
console.log(person.name)
/* 【访问器属性】
* configurable  false
* enumerable
* get函数  默认 undefined
* set函数  默认 undefined
* 添加get set函数
* */
var book = {
  _year: 2014,  // 下划线表示只能经过对象方法访问的属性,可直接访问
  edition:1
}
Object.defineProperty(book,'year',{
  get:function () {
    return this._year
  },
  set:function (val) {
    if(val> 2014){
      this._year = val
      this.edition += val - 2004
    }
  }
})
book.year = 2015;
console.log(book.edition);
console.log(book._year);
/* 同时定义多个属性用   Object.defineProperties() 复数 */
/* 经过 Object.getOwnPropertyDescriptor() 可查看 数据属性和 访问器属性各个值
*  js中任何对象,包括DOM对象和BOM对象都有 Object.getOwnPropertyDescriptor() 方法
*
* */
var desc =Object.getOwnPropertyDescriptor(book,'_year')
console.log(desc.value);
console.log(desc.configurable);
var desc2 =Object.getOwnPropertyDescriptor(book,'year')
console.log(desc2.value);  // undefined
console.log(desc2.configurable); // false

/* 【1.通常模式 】*/
var obj = new Object()
obj.name='name'
console.log('name: '+obj.name);

/* 2.对象字面量 */
var obj2 = {
  name: 'mama'
}
console.log('mama: '+obj2.name);

/*【 3.工厂模式】 */
function cretePerson(name,age) {
  var o = new Object();
  o.name = name;
  o.age = age;
  o.sayName =function () {
    console.log('xx: ' + this.name);
  }
  return o;
}
var person1 = cretePerson('kang',22)
person1.sayName()
/* 【4.构造函数模式】*/
function Person(name, age) {
  this.name=name;
  this.age=age;
  this.sayName2=function () {
    console.log(this.name + 'abccde')  // 等同于  this.sayName2 = new Function('...') 每次实例化都会 new Function(),这是缺陷
  }
}
var per2 = new Person('xiao',33) // Person() 当成构造函数用,有 new
per2.sayName2()
console.log(per2 instanceof Person);

// Person('kangddd',44) //  Person() 当成普通函数用,
// window.sayName2();

var per3 = new Person('aa',33)
var per4 = new Person('bb',33)  // 实例化两个对象,里面有 sayName() 方法,ECMAScript中函数也是对象,每定义一个函数,就是实例化一个对象
console.log('ddd333' + (per3 == per4));  // + 号优先级比 == 高
console.log('eeefff' + false);

/* 【5.原型模式】
* 每一个函数都有 prototype(原型)属性,是一个指针,指向一个对象
* 对象实例共享 prototype 定义的属性和方法
* */
function PersonSix() {

}
PersonSix.prototype.name = 'li'
PersonSix.prototype.sayName3=function () {
  console.log(this.name);
}
var per10 = new PersonSix();
per10.sayName3() // 先查找 per10有没有sayName3()方法,有则返回,没有则查找 prototype是否有 sayname3()方法


/* 每建立一个函数,都有prototype */
function test() {
  return 1
}
console.log(test); // 输入函数  function test(){}
console.log(test.prototype); // 返回一个对象  每建立一个函数,都有 prototype
console.log(test.prototype.constructor);  //  返回 函数  function test(){}

function Person100() {

}
Person100.prototype.name='100name'
Person100.prototype.age='100age'
var p100 = new Person100()
var p101 = new Person100()
p100.name = '110name'  // 实例中新增同名属性覆盖 原型中的 name
console.log(p100.name);  //  '110name'
console.log(p101.name); //   '100name'
delete p100.name;  // 经过  delete 能够找回 原型中的 name
console.log(p100.name); //   '100name'

console.log(p100.hasOwnProperty('name'));  //  判断实例是否有某属性  hasOwnProperty
console.log('name' in p100);  // name存在于实例或者原型都会返回 true
console.log(Object.keys(Person100.prototype));  // ['name','age'] 拿到全部原型属性的数组
console.log(Object.getOwnPropertyNames(Person100.prototype));  // ['constructor','name','age'] 拿到全部原型属性的数组
console.log('ok ? ' + (p100.constructor == Person100));  // 简化前 这里是 true

/* 简化原型语法*/
function Car() {

}
Car.prototype={
  constructor: Car, // 手动指定 constructor ,省略后, car.constructor 就再也不指向  Car
  name:'baoma',
  age:22
}
var car = new Car()
console.log(car.name);
console.log(Car.prototype.constructor);
console.log(car.constructor == Car);  // 简化后,这里返回 false

/* 在 String.prototype中能够找到 substring() 方法 */

/* 原型模式的缺陷是 若是对象中的属性是引用类型,如 数组 , 那么某个实例修改了数组,另外一个实例也拿到了修改后的数据  */

function Dog() {

}
Dog.prototype={
  constructor:Dog,
  friends:['kang','jia']
}
var f1 = new Dog()
var f2 = new Dog()
f1.friends.push('hehe')
console.log(f1.friends);  // ['kang','jia','hehe']
console.log(f2.friends); // ['kang','jia','hehe']

/* 【组合使用构造函数械和原型原式 】*/
function Pig(name,age) {  // 属性写在构造函数中
  this.name = name;
  this.age= age;
  this.friends = ['dd','ee']
}
Pig.prototype={     // 方法写在原型中
  constructor: Person,
  sayName:function () {
    console.log(this.name);
  }
}
var pig1 = new Pig('piga',11)
var pig2 = new Pig('pigb',12)
pig1.friends.push('ff')
console.log(pig1.friends);
console.log(pig2.friends);
console.log(pig1.friends === pig2.friends);  // false
console.log(pig1.sayName === pig2.sayName);  // true
View Code

 闭包css

/* 面向对象继承方法 见 6.3.4原型式继承,一个对象继承另外一个不一样的对象 更好的是 6.3.6寄生组合式继承 */
var a = function () {
  return 5;
}
console.log(a());
/* 递归    严格模式下不能用  arguments.callee时的写法,加多了一个括号,加多一个函数名 */
var factorial = (function f(num) {
  if (num <= 1) {
    return 1;
  } else {
    return num * f(num - 1)
  }
})
console.log(factorial(5));
/* 普通函数fn被调用时,会建立一个包含 this/arguments/参数val的活动对象, 全局执行环境的变量对象(包含this、res、fn)在执行环境的做用域链中则处于第二位*/
function fn(val) {
  return 5 + val
}
var res = fn(4)

/* 闭包:指有权访问另外一个函数做用域中的变量的函数,建立闭包的常见方式,就是在一个函数内部建立另外一个函数*/
function createComparison() {
  return function (obj1, obj2) { // 内部函数会将外部函数  createComparison的活动对象 this等都添加到它的做用域链中,所以闭包比通常函数会占用更多内存,少用
    // ...
  }
}
// 闭包做用域链使闭包只能取得包含函数中任何变量的最后一个值
function fn2() {
  var result = new Array();
  for (var i = 0; i < 10; i++) {
    result[i] = function () {
      return i;
    }
  }
  return result;
}
console.log(fn2()); // 不懂
// 闭包中的 this 指向 window, this通常状况下,谁调用指代谁
var name = 'window'
var obj = {
  name: 'obj',
  getName: function () {
    return function () {
      return this.name
    }
  }
}
console.log(obj.getName());  // function(){ return this.name} 调用 getName() 返回一个函数 ,
console.log(obj.getName()()); // 'window'  调用 getName()() 就会当即调用它返回的函数,即返回一个字符串

function assign() {
  var element = document.getElementById('a');
  var id = element.id
  element.onclick = function () {
    console.log(id);
  }
  element = null; // 把 element 设置为 null , 手动在闭包中释放内存
}

function f2() {
  for (var i = 0; i < 10; i++) {
    console.log(i);
  }
  console.log(i); // undefined 还能够访问,i是定义在f2()函数的活动对象中的
  // console.log(j); // error  not defined
}
console.log(f2());

function f3() {
  (function () {
    for (var i = 0; i < 10; i++) {
      console.log(i);
    }
    console.log(i); // 10   (function(){ ... })() 块级做用域,外部访问不到,可使用本身定义的变量,不受其余干扰
  })()
//  console.log(i);  // error not defined   i 在块级做用域中,外部访问不到,
}
f3()

function Test() {
 var num = 1078;
 return num;
}
console.log(Test()); // 函数名能够大写、中文,
/*
* 特权方法
* */
function f4() {
  var num4 = 4;
  function getNum() {
    return false
  }
  // 特权方法
  this.publicNum = function () {
    return num4
  }
  // 特权方法
  this.publicMothod = function () {
    return getNum()
  }
  //  return num4; 不想返回,能够写个方法返回 ,并用对象的构造函数模式返回
}
console.log(f4());
console.log(new f4().publicMothod());
console.log(new f4().publicNum());


var f6 = function () {
  console.log(666);
}()
View Code

 setTimeout()    少用setInterval()   history()  location.replace()  不能后退到当前页面html

var age = 29; // 使用var 定义后,把 configurable 设置为false 阻止 delete 【面向对象 数据属性 configurable 】
window.color='red'
delete window.age;
delete window.color;
console.log(window.age); // 29
console.log(window.color); // undefined   使用window来定义变量color,能够被 delete
// ECMAScript 是 js的核心,在web中使用js,则BOM是web(window location navigator )核心

// 使用 setTimeout() 超时调用, 少用间歇调用setInterval() ,须要 clearInterval
var num = 0;
var max = 60;
function minute() {
  max--;
  console.log(max);
  if (max > num) {
    setTimeout(minute, 1000)
  } else {
    console.log('ok');
  }
}
setTimeout(minute, 1000) // 倒计时效果
/* location.search  */
var url = 'http://www.baidu.com?name=kang&age=12'
console.log(location.search); // ?name=kang&age=12
/* 取消后退按钮用 location.replace() */
setTimeout(function () {
  location.replace('http://www.baidu.com')  // 不能后退到以前的页面
},1000)
location.reload() // 从新加载 (有可能从缓存中加载 )
location.reload(true) // 从新加载 (从服务器中加载 )
history.go(1)  // 前进一页  history.forward()
history.go(-1) //后退一页  history.back()
//
if(history.length == 0){
  // 这是用户打开窗口后的第一个页面 
}
View Code

 倒计时 setTimeout()   不用 setInterval() java

倒计时
<p id="num">60</p>
<script>
  var max = document.getElementById('num').innerHTML
  var num = 0;
  function minute() {
    max--;
    document.getElementById('num').innerHTML = max
    console.log(max);
    if (max > num) {
      setTimeout(minute, 1000)
    } else {
      console.log('ok');
    }
  }
//  setTimeout(minute, 1000)
</script>
View Code

 document  getElementByClassName classList  readyState  compatMode  outerHTMLnode

console.log(document.title);  // 标题
console.log(window.location.href);
console.log(document.URL); // 网址
console.log(document.domain); // 域名
/*
*  document.forms  全部<form>元素
*  document.images 全部 <img>元素
*  document.links 全部带 href的<a>元素
*  document.anchors 全部带 name的<a>元素 描点
* */
document.write('<script src = "1.js"></script>')
/* 文本 节点分割 */
var element = document.createElement("div")
var textNode  = document.createTextNode('hello world')
element.appendChild(textNode)
document.body.appendChild(element)
var newNode = element.firstChild.splitText(5)  // 文本节点分割
console.log(element.firstChild.nodeValue);
console.log(newNode.nodeValue);

/*
*   <div class="a"></div>
* */
document.getElementsByTagName('div')[0].innerHTML = 444
document.querySelector('.a').innerHTML = 123
document.getElementsByClassName('a')[0].innerHTML = 888  // h5 新增  getElementsByClassName

/*
*   h5 增长  classList 方法     for(var i = 0;i<div.classList.length; i++){...}
*  <div class = 'a b c'>ddd</div>
*  div.classList.remove('a') // 删除a 样式    add() 添加     toggle('c') 切换样式   contains('d') 包含样式
* */

/*
*  h5  DOM焦点功能
*  document.activeElement  判断得到焦点是哪一个元素
*  document.hasFocus() 是否得到焦点了
* */
var button = document.getElementById('mybtn')
button.focus();
console.log(document.activeElement === button); //  true
console.log(document.hasFocus()); // true

/*
*  h5 文档加载属性   readyState    loading 加载中    complete 加载完成
*  if(document.readyState == 'complete'){ ... // 文档加载完成 }
* */

/*
*   渲染模式
 *
* */
if(document.compatMode == 'CSS1Compat'){
  console.log('standards mode');  // 标准模式
}else {
  console.log('quirks mode'); // 混杂模式
}
console.log(document.charset); // utf-8
// h5 新增 document.head (chrome和 safari5 实现了)
var head = document.head || document.getElementsByTagName('head')[0];
/*
*  outerHTML
* <div id="mydiv" data-apptest = '12345' data-appName="hehe">div</div>
* */
document.getElementById('mydiv').outerHTML="<p>this is p</p>"
/* 把 mydiv整个html片段 替换为 新的内容 */
/*
* <div id="mydiv" data-apptest = '12345' data-appName="hehe">div</div>
* 在 div同级以前、以后插入元素,在div里面内容以前、以后插入元素   beforebegin   afterbegin  beforeend  afterend
* 使用 innerHTML outerHTML insertAdjacentHTML  要先把原来的元素相关的事件给删除,减小内存占用
* */
document.getElementById('mydiv').insertAdjacentHTML('beforebegin','<p>pppp</p>')
View Code

 js删除元素的行内样式 removeProperty()    cssText 添加多个样式android

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>abc</title>
</head>
<style>
  .p3{
    position: absolute;top:22px;left:33px;
    color: red;
  }
</style>
<body>
<div id="test">d</div>
<div style="border: 1px solid green;width:200px;height: 300px;position: relative;" >
  <p style="position: absolute;top:22px;left:33px;color:blue;" id="test2">dddddd</p>
  <p style="" class="p3" id="test3">dddddd</p>

</div>
<script src="0.js"></script>
原型对象 p167
<script>
  /*  删除样式,取得默认属性
  *  cssText 批量添加样式、 removeProperty() 删除样式  h5的classList 也能够删除样式
  *   removeProperty() 在不肯定某个给定的CSS属性拥有什么默认值的状况下,能够移除相应的属性,就能够为元素应用默认值
  * */
  var test = document.getElementById('test')
  test.style.color='red'
  test.style.cssText='font-size:50px;color:blue;'  //添加多个样式
  var prop,val
  for(var i =0;i<test.style.length;i++){
//    console.log(test.style[i]);
    prop = test.style[i]
    val = test.style.getPropertyValue(prop)
    console.log(prop + " : " + val);
  }
  test.style.removeProperty('color')

  document.getElementById('test2').style.removeProperty('position')
  document.getElementById('test2').style.removeProperty('color')
  document.getElementById('test3').style.removeProperty('color') // 只能删除行内式,样式选择器的删除不了

  /* getComputedStyle(a,b) a:元素, b:伪元素字符串,如 :after ,没有传 null   ie不支持,用currentStyle   其余浏览器返回值,如border值不一致*/
  var computedStyle = document.defaultView.getComputedStyle(test,null)
</script>
</body>
</html>
View Code

 js 读取样式表的属性  能够动态添加 样式 insertRule ie用addRule    删除样式 deleteRule() ie用 removeRule() 不经常使用ios

<style>
  .test{
    background: blue;
    width:110px;
    height:220px;
  }
  .box{
    background: red;
    width:100px;
    height:200px;
  }
</style>
<body>
<script>
  var sheet = document.styleSheets[0];
  var rules = sheet.cssRules || sheet.rules;
  console.log(rules[0].selectorText);  // 读取样式表的属性值
  console.log(rules[1].style.cssText);
  console.log(rules[0].style.background);
  console.log(rules[0].style.width);
  console.log(rules[0].style.height);
</script>
View Code

偏移量 offset  客户区大小  client 滚动大小 scrollTop web

偏移量
offset  内容+padding+border
offsetHeight offsetWidth offsetLeft offsetTop  p12.2.3 元素大小

客户区大小
client  内容+padding
clientHeight  clientWidth     document.documentElement.clientWidth  低版本用  document.body.clientWidth

滚动大小
 scrollHeight 元素内容高度
 scrollWidth 元素内容宽度   document.documentElement.scrollWidth
 scrollLeft
 scrollTop

getBoundingClientRect()  DOM遍历、DOM范围chrome

每一个元素都有 getBoundingClientRect() , 返回一个矩形对象 left top right bottom   ie8不一致
  DOM遍历 p12.3 NodeIterator、TreeWalker   ie不支持
   DOM范围 p12.4
View Code

 事件 event对象  currentTarget target thiswindows

<script>
  /*  事件都会传 event对象 , ie8之前由 window.event 得到,若是ie使用 <input type='text' onclick="alert(event.type)"> 这里的event就能够直接获取 ,跟DOM同样
  currentTarget target this
   通常状况下,currentTarget === this === target , 当点击区域变大了后, target会变成点击目标,如body,如button等,而 this和currentTarget永远表示调用的对象,这里是body*/
  document.body.onclick=function (e) {
    console.log(e.type); // 'click'   'mouseover'等
    console.log(e.currentTarget === this);
    console.log(e.target === this);
    console.log(e.target);  // 点哪一个是哪一个  button  或  body
    console.log(this);   // 谁调用是谁 body
  }

</script>

js访问form元素简写 、 addEventListener()   事件冒泡 stopPropagation()

<body>
<form action="" name="form1">
  <input type="text" name="username">
  <input type="button" onclick="console.log(username.value)" value="click"> <!-- 输入的值  表单简写  -->
  <input type="button" onclick="console.log(this.value)" value="btn">   <!--  btn -->
  <input type="button" onclick="console.log(value)" value="btn22">   <!--  btn22  表单简写 -->
</form>
<!-- addEventListener('click',function(){},false)
false 表示在冒泡阶段调用事件处理程序,即从当前元素,如div 往上一级,body 等促发
 true 表示在捕获阶段调用事件处理程序,即从body-> div 再到 body的促发,先由外到内的捕获,再由内到外的冒泡

-->
<!--
/* 取消连接的默认行为,如连接跳转,使用  e.preventDefault()
   * 取消事件冒泡,使用 stopPropagation()
   * */
-->
<div id="mydiv" style="border: 1px solid green;width: 200px;height: 200px;">
  <button id="btn">btn</button>
</div>
<script>
  // 只有在事件处理期间,event对象才会存在,一旦事件处理完成,event对象就会被销毁
  document.getElementById('btn').onclick=function (e) {
    e.stopPropagation()  // 阻止后,就不影响
    console.log('btn'); // 点击btn时,也会点到外面的mydiv,会输入两行
  }
  document.getElementById('mydiv').onclick=function () {
    console.log('mydiv');
  }
</script>
</body>

 事件   event

/* 【电子书 13.4】
*  load  页面加载后 window.onload , 全部框架加载完,在框架上触发, 图片加载完,在img上触发, object嵌入内容加载完在 object上触发
*  unload 页面卸载 window.unload ,全部框架卸载完,在框架上触发, object嵌入内容卸载完在 object上触发 ,从一个页面切换到另外一个页面就会发生 unload事件,多用于清除引用,避免内存泄漏
*  abort 用户中止下载过程时,若是嵌入的内容没有加载完,在<object>上触发
* error 当发生javascript错误时在window上面触发,当没法加载图像在img触发,当没法加载嵌入内容在<object>触发
* select 当选择文本框input 或 textarea 中一或多个字符时触发
* resize 当窗口或框架大小变化在 window 触发, 最大化、最小化也会触发
* scroll 当滚动带滚动条的元素中的内容时,在该元素上面触发 body元素包含所加载页面的滚动条
*
* <script> 在ie9+ 中,只有设置了script的src属性,并添加该元素到文档后,才会开始加载js文件
*  事件中的 shift ctrl alt meta(指windows键盘中的windows键,在苹果机 Cmd键 )
*  e.shiftKey   e.ctrlKey  e.altKey e.metaKey
*  鼠标左中右键  e.button  0 表示左键 1 表示鼠标滚轮 2表示鼠标右键
*  mousewheel 鼠标滚轮事件 有一个 e.wheelDelta 属性,当用户向前滚动鼠标时  wheelDelta是120的倍数,向后滚动鼠标,wheelDelta是-120的倍数
*  火狐用 e.DOMMouseScroll 保存在 e.detail 当用户向前滚动鼠标时  wheelDelta是 -3 的倍数,向后滚动鼠标,wheelDelta是3的倍数
*
*  触摸设备  ios 和 android 没有鼠标, 没有 dbclick
*  轻击可触发  mousemove事件,若是该操做会致使内容变化,将再也不有其余事件发生,若是屏幕没有所以变化,那么会依次发生 mousedown mouseup 和 click 事件
*  mousemove事件也触发 mouseover mouseout事件
*  两个手指在屏幕上且页面随手指移动而滚动时会触发mousewheel和scroll事件 (好像没啥用)
*
*  keydown 用户按下键盘任意键触发,按住不放,会重复触发
*  keypress 键盘字符键、esc键触发,按住不放,会重复触发
*  textInput 文本事件,对keypress的补充,在文本插入文本框以前触发textInput 事件
*  用户按下键盘的字符键后,先触发 keydown事件、再触发 keypress事件,再触发 keyup事件, keydown和keypress是在文本框发生变化以前触发的。 keyup是文本框发生变化以后触发的。
*  【电子书 13.4.4】
* */

pageX  offsetX  screenX clientX  鼠标左中右键,滚轮事件 页面切换事件 unload

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>abc</title>
</head>
<body>
this is 0.html
<script>
  window.onunload=function () {
    console.log('unload'); // 页面跳转,离开当前页面会执行,页面刷新也会执行
  }
</script>
<div id="a" style="border: 6px solid green;width:200px;height: 200px;padding:10px;">div</div>
<div id="b" style="border: 6px solid green;width:200px;height: 200px;padding:10px;">div</div>
<div id="c" style="border: 6px solid green;width:200px;height: 200px;padding:10px;">div</div>
<script>
  document.getElementById('a').onclick=function (e) {
    console.log(e.clientX);
    console.log(e.pageX);  // 以浏览器为起点,页面不滚动,二者一致, 页面滚动,pageX包括滚动条的值
    console.log(e.screenX); // 相对当前屏幕,以PC桌面左上角为起点
    console.log(e.offsetX);  // 限制在点击区域内的位置,除去边框和外边距
  }
  document.getElementById('b').addEventListener('mousedown',function (e) {
    console.log(e.button);  // 判断鼠标左中右键     e.button的值  0 是左键 1 是鼠标滚轮  2是右键
  },false)
  document.getElementById('c').addEventListener('mousewheel',function (e) {
    console.log(e.wheelDelta);
  },false)
  document.getElementById('c').addEventListener('DOMMouseScroll',function (e) {
    console.log(e.detail);  // 火狐用  DOMMouseScroll
  },false)
</script>
</body>
</html>

 contextmenu冒泡事件 右键菜单

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>abc</title>
</head>
<body>
contextmenu冒泡事件 上下文菜单(右键菜单)

<div id="mydiv" style="border: 1px solid green;width:800px;height: 1000px;">右键菜单</div>
<div id="mymenu" style="border: 1px solid green;width:200px;height:200px;display:none;position: absolute;top:80px;left:20px;">右键菜单
</div>

<script>
  // 右键菜单
  var mydiv = document.getElementById('mydiv')
  var mymenu = document.getElementById('mymenu')
  mymenu.addEventListener('contextmenu', function (e) {
    e.preventDefault() // 阻止默认的浏览器右键菜单
  })
  mydiv.addEventListener('contextmenu', function (e) {
    e.preventDefault()  // 阻止默认的浏览器右键菜单
    mymenu.style.left = e.clientX + 'px'
    mymenu.style.top = e.clientY + 'px'
    mymenu.style.display = 'block'
  })
  document.addEventListener('click', function () {
    mymenu.style.display = 'none'
  })
</script>
<script>
  window.addEventListener('beforeunload',function (e) {  // 窗口关闭时,弹窗是否关闭
    var res = 'abc'
    e.returnValue=res  // ie能够
    return res  // chrome 返回不了'abc'
  })
</script>
load事件会在页面中一切都加载完毕时触发,包括一堆外部资源
DOMContentLoaded事件则在造成完整的DOM树以后就会触发,不理会图像、JS文件、css文件是否已经下载完毕,用户能够早点与页面进行交互 ie9+支持
不支持的浏览器,处理以下  setTimeout(function(){ ... },0); // 不必定有效
readystatechange事件 chrome不支持! ie、firefox支持
pageshow和pagehide事件  在浏览器后退和前进按钮时缓存数据,不会用 ,ie9不兼容
hashchange事件 url中'#'号后面的字符串发生变化时,监听事件
window.addEventListener('hashchange',function(e){console.log(location.hash);})  ie8+ 支持
手机设备旋转事件 deviceorientation devicemotion    android版 webkit ?
触摸事件 touchstart touchmove(调用 preventDefault()能够阻止滚动 ) touchend
触摸事件(包括鼠标事件的顺序,会冒泡)
touchstart / moseover / mousemove(一次) / mousedown / mouseup /click/ touchend
手势事件(要两个手指在元素范围内才触发,会冒泡,只放一个手指会触发 touchstart事件) ios才支持
gesturestart
gesturechange
gestureend
</body>
</html>
相关文章
相关标签/搜索