学习笔记 二月 23, 2020

关于 JS DOM编程艺术(第二版)

文章字数 9.8k 阅读约需 9 mins. 阅读次数 1000000

关于《Javascript Dom 编程艺术(第二版)》

书籍封面

变量的作用域

如果一个函数的内部使用了全局变量的名字,即使本意是用于局部变量,JS也会认为是全局变量,当对这个变量进行赋值,全局变量也会被改变。

let global = 1;
function para(){
  let local = 10;
  global += local;
}
para();
alert(global);    //此时global=11

此时,解决这个问题只需要一个小的修改

let global = 1;
function para(){
  let local = 10;
  let global = 0; 
  return global+local;
}
para();
alert(global);    //此时global=10

内建对象

数组也是一种内建对象,内建对象是JS已经定义好可以直接用的方法。

const beatles = new Array(); //定义新数组
const currenttime = new Date();    //获得当前日期
const year = currenttime.getYear();    //获得年
const month = currenttime.getMonth();    //获得月
const day = currenttime.getDay();    //获得日
...
const num = 5.1234
const integer = Math.round(num); //四舍五入取整

Math内建对象

assert(Math.ceil(0.3),"答案为1");    //取值为浮点数“大于”的整数
assert(Math.floar(0.9),"答案为0"); //与ceil相反,取“小于”的整数
assert(Math.round(0.5),"答案为1");
assert(Math.round(0.4),"答案为0");    //常用的四舍五入

3种DOM方式获取元素

document.getElementById('Id');    //获得一对一
document.getElementByTagName('Tagname');    //获得一个数组
document.getElementByClassName('class');    //获得的也是一个数组

//特殊
<div class="div1 div2 div3"></div>
...
let div = document.getElementByClassName('div1 div2 div3'); //顺序颠倒也可以
assert(div.length != null,"这是一个数组");

高效加载JS代码文件

包含脚本的最佳方式就是使用外部文件

<script src="scripts/function1.js"></script>
<script src="scripts/function2.js"></script>
<script src="scripts/function3.js"></script>
<script src="scripts/function4.js"></script>

这种方式是不高效率的,可以吧4个JS文件放置在一个JS文档中,页面发送请求次数减少。同时,当一个Html文件需要多个JS文件需要使用,建议将JS代码放在一个scripts文件夹,提高性能。

再者,脚本文件建议放置最后位置,如下图显示。

<!Doctype html>
  <html>
      <head>...</head>
        <body>
              ....
              <script src="./scripts/math.js"></script>        //在body最后
      </body>
  </html>

网页会等其余所有文件加载完成后才会加载脚本,不会影响用户体验。

同时,压缩脚本也是一种办法,将原来的工作副本xxx.js复制粘贴一份,作为精简文件xxx.min.js,将文件空格,注释清空。

function preparelinks(){if(!document.getElementsByTagName) return false;let tagArrays=document.getElementsByTagName("a");for(let index=0;index<tagArrays.length;index++){
...

网上有代码压缩工具,可以百度下载。

调用JS函数方法

function popUp(URL){
  window.open(URL,"新网页","width:350 height:400");
  //BOM下window对象的open函数:window.open(url,name,features); 
}

“javascript:伪协议调用”

<a href="javascript:popUp('http://shermanblog.xyz');">点击链接</a>

“内嵌的事件处理函数”

<a href="#" onclick="popUp('http://shermanblog.xyz');return false;">点击链接</a>

但是这两种方法一旦浏览器禁用JS就毫无作用。解决如下:

<a href="http://shermanblog.xyz" onclick="popUp('http://shermanblog.xyz');return false">点击链接</a>    

“分离Javascript”—最好的解决方式

<script src="./test.js"></script>    //调用外部JS文件
<a href="http://shermanblog.xyz" class="popup">点击连接</a>

...
//外部test.js
window.onload = preparelinks;
function preparelinks(){
let tagArrays = document.getElementByTagName("a");
for(let index= 0; index < tagArrays.length; index++){
  if(tagArrays[index].getAttribute("class")==="popup"){
             tagArrays[index].onclick = function(){
          popUp(tagArrays.getAttribute('href'));
          return false;
                };
         }
}
}

function popUp(URL){
  window.open(URL,"新网页","width:350 height:400"); 
}

平稳退化:不论是失去JS,CSS文件不会影响网页的内容生成。

对象检测

检测一个浏览器是否支持DOM语句,比如getElementsByTagName

function preparelinks(){
//执行下面语句之前,增加一个判断
if(!document.getElementsByTagName) return false;
//若是不支持这个判断,浏览器会跳过这个函数,不影响网页
let tagArrays = document.getElementsByTagName("a");
for(let index= 0; index < tagArrays.length; index++){
...

网页加载完毕触发onload事件

网页加载完成后立刻执行外部的JS脚本

function Fun(){.....}

window.onload = Fun;

多个JS脚本时:

function Fun1(){...}
function Fun2(){...}

window.onload = function(){
  Fun1();
  Fun2();
}

编写一个addLoadEvent函数,简化window.onload()(*important)

function addLoadEvent(fun){
  let oldonload = window.onload;
  if(typeof window.onload != 'function'){
     window.onload = fun;
     }else{
    window.onload = function(){
      oldonload();
      fun();
    }
  }
}

之后调用Fun1,Fun2只需要

addLoadEvent(Fun1);

addLoadEvent(Fun2);

Return的难点

return true; //函数返回正确的处理结果,等于 执行符

return false; //函数取消作用,终止处理,等于 终止符

return 表达式; //表达式的结果作为返回结果

没有特殊情况,一般不加return

检查再优化代码

是否平稳退化❓
是否JS CSS与Html分离了❓
是否向后兼容❓
性能尽可能优化了吗❓

动态创建标记

传统方法

1.document.write(“语句”);

快捷的将字符串添加到文档body中

<body>
<script>document.write("This is a new message.")</script>
</body>

2.inner.html

可以读,也可以写,比doucmenr.write更加快速,但是会替换掉所有的内容,比较霸道。

DOM方法

一个文档可以看作是一个DOM树,如果想要增加内容,就要在某个节点后增加文本节点。用到的方法以下:

document.createElement(‘元素名’) //创建一个元素节点

document.createTextNode(‘内容’) //创建一个文本节点

document.appendChild(‘节点名’) //将节点作为子节点接上去

document.insertBefore(‘新节点名’,’目标节点名’) //将元素节点作为兄弟节点插入到目标节点前面

parentNode //父节点

lastChild //该节点下的最后一个子节点

firstChild //该节点下的第一个子节点 相当 于childNode[0]

nextSibling //该节点的下一个兄弟节点

⚠️不存在document.insertAfter(‘新节点名’,’目标节点名’)**这个方法⚠️

但是可以写一个方便使用的脚本并且收录到JS中随时调用

function insertAfter(newElement,targetElement){
  let parentNode = targetElement.parentNode;
  if(targetElement == parentNode.lastChild){
    parentNode.appendChild(newElement);
  }else{
    parentNode.insertBefore(newElement,targetElement.nextSibling);
  }
}

Dom获得Style属性

<p id="p1" style="color:grey; font-family:'Arial' ; font-weight:bold">This is a test.</p>
...
let para = document.getElmentById('p1');
alert(typeof para.style); //结果为一个对象
alert(para.style.color); //结果等于grey
alert(para.style.fontWeight);    //结果为bold

注意⚠️的是:font-weight在DOM中用驼峰命名法表示fontWeight,因为“-”在语句中会被认为是减号,会报错

DOM属性的特殊用法

当函数发生这么一种情况:

​ “既不能使用全局变量,也不能使用局部变量,并且还是需要这么一种东西能够介于他们两者之间的变量。”

只与某个特定元素有关的变量是存在的,而且我们经常会使用就是“属性”。Javascript允许我们为元素创建属性:

element.property = "value";
//只要你愿意,可以任意定一个名为myName的属性,并且值为Sherman
element.myName = "Sherman";

这很像是在创建一个变量,但区别是这个变量专属于某个特定的元素。我们创建一个元素属性的变量,它已经存在,并且可以在函数内使用任何方法,避免了全局变量和局部变量的BUG


以上是个人认为书中比较重要的知识点,欢迎楼下评论

0%