JavaScript DOM编程艺术笔记

本书在一些基础的JavaScript语法上,通过一个个小例子讲解了简单的dom操作,最后把例子综合起来做成一个网站。难得可贵的是其中的平稳退化,渐进增强的web设计理念——确保页面在没有JavaScript的情况下也能正常工作。其中对兼容性的考虑和结构、样式、行为相分离的思想也是值得学习的。


1. 什么是JavaScript

JavaScript是一种运行在浏览器端的脚本语言。JavaScript主要包括ECMAscript(规定标准JavaScript的语法)、BOM(浏览器窗口对象的一组API )、和重要的DOM(文档对象模型,即如何操作文档,对文档的内容进行抽象和概念化的方法)。
至于JavaScript的弱类型语言、解释性语言和基于原型的特性在此不再赘述。

2.通用型函数

  1. onload让函数在网页加载完毕后立即执行。else,如果window.onload上已经绑定了函数,那么就将新函数追加到现有指令下面。
function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      oldonload();
      func();
    }
  }
}
  1. inserAfter函数在元素后插入一个新元素。 如果目标元素是其父元素的最后一个子元素,那么就插入在其父元素后面;如果不是,那么就插入在目标元素的下一个兄弟元素前面。
function insertAfter(newElement,targetElement) {
  var parent = targetElement.parentNode;
  if (parent.lastChild == targetElement) {
    parent.appendChild(newElement);
  } else {
    parent.insertBefore(newElement,targetElement.nextSibling);
  }
}
  1. 类jQuery的addClass()添加类名函数
function addClass(element,value) {
  if (!element.className) {
    element.className = value;//如果没有类名则直接添加
  } else {
    newClassName = element.className;
    newClassName+= " ";
    newClassName+= value;//如果有类名将其转化为字符串连接起来
    element.className = newClassName;
  }
}

3. JavaScript图片库

function prepareGallery() {
  if (!document.getElementsByTagName) return false;
  if (!document.getElementById) return false;
  if (!document.getElementById("imagegallery")) return false;
  var gallery = document.getElementById("imagegallery");
  var links = gallery.getElementsByTagName("a");
  for ( var i=0; i < links.length; i++) {
    links[i].onclick = function() {
      return showPic(this);
    }
    links[i].onkeypress = links[i].onclick;
  }
}

这里prepareGallery函数获得图片库每个a标签的值,并对他们执行showPic函数。这里前三句可以保证浏览器部分不支持JavaScript或者imagegallery不存在时脚本也可以正常工作,即渐进增强。

function showPic(whichpic) {
  if (!document.getElementById("placeholder")) return true;
  var source = whichpic.getAttribute("href");
  var placeholder = document.getElementById("placeholder");
  placeholder.setAttribute("src",source);
  if (!document.getElementById("description")) return false;
  if (whichpic.getAttribute("title")) {
    var text = whichpic.getAttribute("title");
  } else {
    var text = "";
  }
  var description = document.getElementById("description");
  if (description.firstChild.nodeType == 3) {
    description.firstChild.nodeValue = text;
  }
  return false;
}

这里showPic函数将获得a标签的src和alt属性,并将其赋值给placeholder。配合prepareGallery可以实现点击a标签更新img标签placeholder的src属性和p标签description的nodevalue,从而做到图片切换的效果。
优点:

  1. 将onclick事件处理程序从a标签中解放出来,不仅做到结构和行为相分离,而且简化了代码。
  2. 把showPic函数单独抽象出来,其中的whichpic参数通过传入不同的参数,使showpic函数具有一定的普适性(组件化)。
  3. 遍历a标签,对每个标签执行showpic函数,而不是每个a标签依次调用showpic函数,简化了代码,return false取消a链接默认的跳转行为。
    后面还会介绍将缩略图包含在a标签内,使页面更美观。结构和行为相分离的理念要求我们动态生成img标签placeholder的src属性和p标签description,因为这些标签仅仅是为了showpic函数服务的。结构和行为分离固然很好,但这同时也会增加js的代码量,其中的平衡也是实际开发中要考虑的因素。

4. Ajax异步加载页面技术

优势:

  1. 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
  2. 用户可以继续浏览页面并与页面交互,通过ajax可以按需加载和创建页面内容,而不会打断用户的浏览体验,从而使web应用呈现出功能丰富,交互敏捷,类似桌面应用般的体验。

XMLHttpRequest是ajax技术的核心,用于在后台与服务器交换数据。ajax承担浏览器和服务器端的中间人的角色,JavaScript通过ajax可以自己发送请求,也可以自己处理相应。

  1. 创建ajax对象
var xmlhttp;
if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
  1. 向服务器发送请求
    将请求发送到服务器,我们使用XMLHttpRequest对象的open()方法。
open(method,url,async);

method:请求的类型;GET 或 POST;url:文件在服务器上的位置;async:true(异步)或 false(同步);大部分情况下使用GET类型。

  1. 请求实例
    `
    function getNewContent(){
    var request = getHTTPObject();//创建ajax对象
    if(request){
    request.open("GET","example.txt",true);//向服务器端(此处是txt文件)发送请求
    request.onstatechange = function(){
    if(request.readyState == 4){//readyState为4即请求成功
    var para = document.createElement("p");
    var txt = document.createTextNode(request.responseText);
    para.appendChild(txt);
    document.getElementById("new").appendChild(para);//将请求的内容插入到id为new的div中
    }
    };
    request.send(null);//将请求发送到服务器 string类型
    }else{
    alert("Sorry,your browser does not support ajx")
    }
    }
    addLoadEvent(getNewContent);

`

5. 实现移动元素效果

function moveElement(elementID,final_x,final_y,interval) {//参数代表元素id 最终xy位置 移动速度
  if (!document.getElementById) return false;
  if (!document.getElementById(elementID)) return false;
  var elem = document.getElementById(elementID);
  if (elem.movement) {//属性不会产生局部变量和全局变量的作用域问题 清除定时器
    clearTimeout(elem.movement);
  }
  if (!elem.style.left) {
    elem.style.left = "0px";
  }
  if (!elem.style.top) {
    elem.style.top = "0px";
  }
  var xpos = parseInt(elem.style.left);
  var ypos = parseInt(elem.style.top);
  if (xpos == final_x && ypos == final_y) {
    return true;
  }
  if (xpos < final_x) {
    var dist = Math.ceil((final_x - xpos)/10);//这个公式可以实现移动动画先快后慢的效果
    xpos = xpos + dist;
  }
  if (xpos > final_x) {
    var dist = Math.ceil((xpos - final_x)/10);
    xpos = xpos - dist;
  }
  if (ypos < final_y) {
    var dist = Math.ceil((final_y - ypos)/10);
    ypos = ypos + dist;
  }
  if (ypos > final_y) {
    var dist = Math.ceil((ypos - final_y)/10);
    ypos = ypos - dist;
  }
  elem.style.left = xpos + "px";
  elem.style.top = ypos + "px";
  var repeat = "moveElement('"+elementID+"',"+final_x+","+final_y+","+interval+")";
  elem.movement = setTimeout(repeat,interval);//setTimeout递归调用自己可以实现类似setInterval每一帧结束后再次调用定时器的功能 
}//但是递归调用浪费空间时间,存在效率问题

利用此函数可以实现图片切换或者轮播之类的效果。

6. 最后的综合项目 即大作业

预览效果: https://richardyou.github.io/JavaScript-DOM-/index.html
代码地址:https://github.com/richardyou/JavaScript-DOM-

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,837评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,551评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,417评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,448评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,524评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,554评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,569评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,316评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,766评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,077评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,240评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,912评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,560评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,176评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,425评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,114评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,114评论 2 352

推荐阅读更多精彩内容