js-事件,BOM,DOM(2019/5/28)

JS --- 事件,BOM,DOM


一、 事件

事件(Event)是 JavaScript 应用跳动的心脏 ,进行交互,使网页动起来。
当我们与浏览器
中 Web
页面进行某些类型的交互时,事件就发生了。事件可能是用户在某些内容上的点击、
鼠标经过某个特定元素或按下键盘上的某些按键。事件还可能是 Web
浏览器中发生的事情,
比如说某个 Web 页面加载完成,或者是用户滚动窗口或改变窗口大小。
通过使用 JavaScript
,你可以监听特定事件的发生,并规定让某些事件发生以对这些事件
做出响应。

1. 作用


(1)验证用户输入的数据。
(2)增加页面的动感效果。
(3)增强用户的体验度


2. 事件类型
JavaScript 可以处理的事件类型为:鼠标事件、键盘事件、 HTML 事件。

Window 事件属性 :针对 window 对象触发的事件(应用到 <body> 标签)

Form 事件 :由 HTML 表单内的动作触发的事件(应用到几乎所有 HTML
元素,但最常用
在 form 元素中)

Keyboard 事件 : 键盘事件

Mouse 事件 :由鼠标或类似用户动作触发的事件

Media 事件 :由媒介(比如视频、图像和音频)触发的事件(适用于所有 HTML
元素,但
常见于媒介元素中,比如 <audio>、 <embed>、 <img>、 <object> 以及
<video>)
几个常用的事件:
onclick 、 onblur 、 onfocus 、 onload 、 onchange、 onmouseover、
onmouseout、
onkeyup、 onkeydown
onload:当页面或图像加载完后立即触发
onblur:元素失去焦点
onfocus:元素获得焦点
onclick:鼠标点击某个对象
onchange:用户改变域的内容
onmouseover:鼠标移动到某个元素上
onmouseout:鼠标从某个元素上离开
onkeyup:某个键盘的键被松开
onkeydown:某个键盘的键被按下

3. 事件流和事件模型

我们的事件最后都有一个特定的事件源, 暂且将事件源看做是 HTML
的某个元素, 那么当\一个 HTML
元素产生一个事件时,该事件会在元素节点与根节点之间按特定的顺序传播,
路径所经过的节点都会受到该事件,这个传播过程称为 DOM 事件流。

事件顺序有两种类型: 事件捕获和事件冒泡。

冒泡和捕获其实都是事件流的不同表现,这两者的产生是因为 IE 和 Netscape
两个大公司\完全不同的事件流概念产生的。(事件流:是指页面接受事件的顺序)

IE 的事件流是事件冒泡,
Netscape 的事件流是事件捕获流。

3.1事件冒泡
IE的事件流叫做事件冒泡,即事件开始时由最具体的元素接受,然后逐级向上传播到较为
不具体的节点(文档)。 例如下面的:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JavaScript</title>
</head>
<body>
<div id="myDiv">Click me</div>
</body>
</html>

如果点击了页面中的<div>元素,那么这个 click 事件会按照如下顺序传播:
1、 <div>
2、 <body>
3、 <html>
4、 document
也就是说, click
事件首先在<div>元素上发生,而这个元素就是我们单击的元素。然后,
click 事件沿 DOM 树向上传播,在每一级节点上都会发生,直到传播到 document
对象。
所有现代浏览器都支持事件冒泡,但在具体实现上还是有一些差别。

3.2事件捕获

Netscape
提出的另一种事件流叫做事件捕获,事件捕获的思想是不太具体的节点应该更早
接收到事件,而最具体的节点应该最后接收到事件。事件捕获的用意在于在事件到达预定目标
之前捕获它。还以前面的例子为例。那么单击<div>元素就会按下列顺序触发
click 事件:
1、 document
2、 <html>
3、 <body>
4、 <div>
在事件捕获过程中, document 对象首先接收到 click 事件,然后沿 DOM
树依次向下,一
直传播到事件的实际目标,即<div>元素。
虽然事件捕获是 Netscape
唯一支持的事件流模式,但很多主流浏览器目前也都支持这种事
件流模型。 尽管"DOM2 级事件"规范要求事件应该从 document
对象开始捕获,但这些浏览器都是从 window 对象开始捕获的。
3.3DOM 事件流\

"DOM2 级事件"规定的事件流包括三个阶段:
事件捕获阶段、处于目标阶段和事件冒泡
阶段。首先发生的是事件捕获阶段,为截获事件提供了机会。然后是实际的目标接收到事件。
最后一个阶段是冒泡阶段,可以在这个阶段对事件做出响应。

image.png

4. 事件处理程序
事件就是用户或浏览器自身执行的某种动作。 例如 click、 load 和 mouseover
都是事件的名\字, 而响应某个事件的函数就叫做事件处理程序(或事件侦听器)
。事件处理程序的名字以"on"开头,因此 click 事件的事件处理程序就是
onclick,为事件指定处理程序的方式有好几\种。

4.1 HTML 事件处理程序

某个元素支持的每种事件,都可以用一个与相应事件处理程序同名的 HTML
特性来指定。
这个特性的值应该是能够执行的 JavaScript 代码:

--
<input type="button" value="Press me" onclick="alert('thanks');"
--

这样做有一些缺点,
例如耦合度过高,还可能存在时差问题(当用户点击按钮时,处理函
数还未加载到,此时处理函数是单独写的一段 js 代码)
,而且在不同的浏览器上可能会有不同的效果。

4.2 DOM0 级事件处理程序

通过 JavaScript
指定事件处理程序的传统方式,就是将一个函数赋值给一个事件处理程序
属性。这种方式被所有现代浏览器所支持。
这种方式首先必须取得一个要操作的对象的引用,
每个元素都有自己的事件处理程序属性,这些属性通常全都小写,例如
onclick,然后将这种属
性的值设为一个函数,就可以指定事件处理程序了。 例如:


<body>
<button id="myBtn">按钮</button>
<script type="text/javascript">
var btn = document.getElementById('myBtn')
btn.onclick = function(){
alert('you click a button')
}
</script>
</body>


以这种方式添加的事件处理程序会在事件流的冒泡阶段被处理。
而且,只能为同一个元素
的同一个事件设定一个处理程序(覆盖), 也可以通过删除 DOM0
级方法指定的事件处理程序,
只要将属性值设为 null 即可:

--
btn.onclick = null


4.3 DOM2 级事件处理程序

"DOM2 级事件"定义了两个方法,用于处理指定和删除事件处理程序的操作:
addEventListener()和 removeEventListener()。

所有 DOM 节点都包含这两个方法,并且他们都接受 3 个参数:

要处理的事件名、作为事件处理程序的函数和一个布尔值。

最后这个布尔值参数如果是 true,则表示在捕获阶段调用事件处理程序;如果是
false 则表示在冒泡阶段调用事件处理程序。


<body>
<button id="myBtn">按钮</button>
<script type="text/javascript">
var btn = document.getElementById('myBtn')
btn.addEventListener('click',function(){
alert('you add a eventListener by DOM2')
},false)
btn.addEventListener('click',function(){
alert('you add a eventListener by DOM2 again')
},false)
function thread(){
alert('you add a eventListener by DOM2 第三次')
}
btn.addEventListener('click',thread,false)
btn.removeEventListener('click',thread,false)
</script>
</body>


这种方式可以为同一个元素的同一个事件添加多个处理函数。
还可删除事件处理函数,注
意, 在删除的时候,不能删除匿名处理函数。

二、 BOM

**
**ECMAScript 是 JavaScript 的核心,但如果要在 Web 中使用
JavaScript,那么 BOM(浏览
器对象模型)则无疑才是真正的核心。 BOM
提供了很多对象,用于访问浏览器的功能,这些功能与任何的网页内容无关。
多年来,缺少事实上的规范导致 BOM
既有意思又有问题,因为浏览器厂商会按照各自的想法随意去扩展它。于是,浏览器之间共有的对象就成为了事实上的标准。这些对象在浏览器中得以存在,很大程度上是由于他们提供了与浏览器的互操作型。
为了把浏览器中 JavaScript 最基本的部分标准化,已经将 BOM
的主要方面纳入了 HTML5 的规范当中。

2.1 Window 对象

BOM 的核心对象是 window,它表示浏览器的一个实例。 window
对象有双重角色,它既是
通过 JavaScript 访问浏览器窗口的一个接口,又是 ECMAScript 规定的 Global
对象。这意味着在网页中定义的任何一个对象、变量和函数,都以 window 作为其
Global 对象,因此有权访问parseInt()等方法。
如果页面中包含框架,则每个框架都拥有自己的 window 对象,并且保存在frames
集合中。在 frames 集合中,可以通过数值索引(从 0
开始,从左至右,从上到下)或者框架的名称来访问相应的 window 对象。

2.1.1window对象方法

1)系统对话框

浏览器通过(实际是 window
对象的方法)alert()、confirm()、prompt()方法可以调用对话框向用户显示消息。

(1)消息框:alert, 常用。

alert() 方法用于显示带有一条指定消息和一个 OK 按钮的警告框。

(2)输入框:prompt,返回提示框中的值。

prompt() 方法用于显示可提示用户进行输入的对话框。

参数(可选):

第一个参数:要在对话框中显示的纯文本。

第二个参数:默认的输入文本。

(3)确认框:confirm,返回 true/false.

confirm() 方法用于显示一个带有指定消息和 OK 及取消按钮的对话框。

2)打开窗口

window.open()方法既可以导航到一个特定的 URL 也可以用来打开一个新的窗口

_self、_parent、_top、_blank

3)关闭窗口

window.close():关闭窗口。

只能关闭被open打开的窗口

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>window对象</title>
    </head>
    <body>
        <button onclick="openAlert()">alert</button>
        <button onclick="openpPrompt()">prompt</button>
        <button onclick="openCinfirm()">confirm</button>
        <br /><br />
        <button onclick="openPage()">打开页面</button>
        <button onclick="closePage()">关闭页面</button>
    </body>
    <!--
        Window对象
            1)系统对话框
                浏览器通过(实际是 window 对象的方法)alert()、confirm()、prompt()方法可以调用对话框向用户显示消息。
            (1)消息框:alert, 常用。
                alert() 方法用于显示带有一条指定消息和一个 OK 按钮的警告框。
            (2)输入框:prompt,返回提示框中的值。
                prompt() 方法用于显示可提示用户进行输入的对话框。
                参数(可选):
                 第一个参数:要在对话框中显示的纯文本。
                第二个参数:默认的输入文本。
                   (3)确认框:confirm,返回 true/false.
              confirm() 方法用于显示一个带有指定消息和 OK 及取消按钮的对话框。
              
            2)打开窗口
                window.open()方法既可以导航到一个特定的 URL 也可以用来打开一个新的窗口
                _self、_parent、_top、_blank
            3)关闭窗口
                window.close():关闭窗口。
                只能关闭被open打开的窗口
    -->
    
    <script type="text/javascript">
        /**
         * 打开弹出框
         */
        function openAlert() {
            window.alert("这是弹出框");
            console.log("。。。");
        }
        
        /**
         * 输入框
         */
        function openpPrompt() {
            var name = window.prompt("请输入用户名:","");
            alert("输入的值为:" + name);
        }
        
        /**
         * 确认框
         */
        function openCinfirm() {
            var flag = window.confirm("您确认要删除这条记录吗?");
            if (flag) {
                alert("删除成功...");
            } else {
                alert("没事儿别瞎点。。。");
            }
        }
        
        /*window.open()方法*/
        function openPage () {
            //window.open();// 打开新的空白页(新开的)
            // window.open("http://www.baidu.com");
            // window.open("http://www.baidu.com",'_self');
            // window.open("index.html");
            window.open("01-window对象.html","_self");
        }
        
        /**
         * 关闭当前页面
         */
        function closePage () {
            window.close(); // Scripts may close only the windows that were opened by it.
        } 
        
        
        
    </script>
</html>


4) 时间函数
setTimeout() : 在指定的毫秒数后调用函数或计算表达式。
通过返回的标识也可以
cliearTimeout(id) 来清除指定函数的执行

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>时间函数</title>
</head>
<body onload="init();">
<h1 id="h1"></h1>
<button onclick="stopShow()">时间停止</button>
</body>

<script type="text/javascript">
    //延迟 3 秒后出现 alert
    function hello() {
        alert("对不起, 要你久候");
    }
    setTimeout("hello()", 3000);
    var timeout;
    function init(){
//拿到当前时间
        var date = new Date();
        var time = date.toLocaleString();
//拿到相应对象
        var h1 = document.getElementById('h1');
//根据需求添加样式
        if(0==date.getSeconds()){ //当时间的秒数变成 0 时,显示红色字体
            h1.innerHTML = '<span style="color:red">'+time+'</span>';
        } else {
            h1.innerHTML = time;
        }
        /*
         * 定时操作,只执行一次
         第一个参数:执行的方法;第二个参数:定时,单位是毫秒
         * */
        setTimeout(init,1000); //等多少时间来执行
    }
    //window.setTimeout(init,1000);//只执行一次
    //停止操作
    function stopShow () {
        clearTimeout(timeout);
    }
</script>
</html>


 

2.2.2 histroy 对象

history 对象是历史对象。 包含用户(在浏览器窗口中)访问过的 URL。
history 对象是
window 对象的一部分,可通过 window.history 属性对其进行访问。

history 对象的属性: length, 返回浏览器历史列表中的 URL 数量。

history 对象的方法:

back():加载 history 列表中的前一个 URL。
forward():加载历史列表中的下一个
URL。当页面第一次访问时,还没有下一个 url。
go(number|URL): URL 参数使用的是要访问的 URL。而 number
参数使用的是要访
问的 URL 在 History 的 URL 列表中的相对位置。 go(-1),到上一个页面

2.2.3 location 对象

location 对象是 window
对象之一,提供了与当前窗口中加载的文档有关的信息,还提供
了一些导航功能。 也可通过 window.location 属性来访问。
location 对象的属性 href:设置或返回完整的 URL
location 对象的方法
reload():重新加载当前文档。
replace():用新的文档替换当前文档。

<script type="text/javascript">
function openSXT(){
//没有历史记录,用新的文档替换当前文档
//window.location.replace("http://www.baidu.com");
//console.log(window.location.href);//获取完整的 url
window.location.href = "http://www.baidu.com";
}
</script>
<body>
<input type="text" name="" id="" value="" />
<input type="button" name="" id="" value="刷新"
onclick="window.location.reload();" />
<input type="button" name="" id="" value="SHSXT 官网"
onclick="openSXT();" />
</body>


2.2.4 document 对象

每个载入浏览器的 HTML 文档都会成为 Document 对象。 Document
对象使我们可以从脚
本中对 HTML 页面中的所有元素进行访问。 Document 对象是 Window
对象的一部分, 也可通过 window.document 属性对其进行访问。
document 对象的 body 属性,提供对<body>元素的直接访问, cookie
属性,用来设置
或返回与当前文档有关的所有 cookie, write()方法,向文档写 HTML
表达式或 JavaScript 代码。
还有其他属性和方法。 在 Document 对象中讲解。
该对象作为 DOM 中的核心对象

四:DOM: Document Object Model 文档对象模型

要实现页面的动态交互效果, bom 操作远远不够, 需要操作 html
才是核心。如何操作
htm, 就是 DOM。 简单的说, dom 提供了用程序动态控制 html 接口。

DOM
即文档对象模型描绘了一个层次化的节点树,运行开发人员添加、移除和修改页面的某一部分。

dom 处于javascript 的核心地位上。
每个载入浏览器的 HTML 文档都会成为 Document 对象。 Document
对象使我们可以从脚
本中对 HTML 页面中的所有元素进行访问。 Document 对象是 Window
对象的一部分,可通过window.document 属性对其进行访问。

4.1 节点

加载 HTML 页面时, Web 浏览器生成一个树型结构,用来表示页面内部结构。
DOM 将这
种树型结构理解为由节点组成,组成一个节点树。 对于页面中的元素,
可以解析成以下几种类型的节点:

image.png

html -->文档节点

div -->元素节点

title -->属性节点


image.png

4.2、 元素节点的操作

当 HTML 文档在被解析为一颗 DOM
树以后,里面的每一个节点都可以看做是一个一个的
对象,我们成为 DOM 对象, 对于这些对象,我们可以进行各式各样的操作,
查找到某一个或者一类节点对象,
可以创建某种节点对象,可以在某个位置添加节点对象,甚至可以动态地删除节点对象,
这些操作可以使我们的页面看起来有动态的效果,后期结合事件使用,就能让我们的页面在特定时机、特定的事件下执行特定的变换。

1. 获取节点
在进行增、删、改的操作时,都需要指定到一个位置,
或者找到一个目标,此时我们就可以通过 Document
对象提供的方法,查找、定位某个对象(也就是我们说的节点) 。

注意: 操作 dom 必须等节点初始化完毕后,才能执行。 处理方式两种:
(1)把 script 调用标签移到 html 末尾即可;
(2)使用 onload 事件来处理 JS,等待 html 加载完毕再加载 onload
事件里的 JS。

image.png

测试:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>DOM获取节点</title>
</head>
<body>

<!--javascript:void(0); 伪协议,表示a标签不执行href属性的跳转行为,而去执行点击事件-->

<p id="p1" class="para">A段落<span>文本</span></p>
<p id="p1" class="para">B段落</p>
<input type="text" name="txt" value="galg"/>
<input type="checkbox" name="hobby" value="游泳" />游泳
<input type="checkbox" name="hobby" value="篮球" />篮球
<input type="checkbox" name="hobby" value="足球" />足球
<hr />
<a href="javascript:void(0);" onclick="testById();">按照 id 获取
    元素</a>
<a href="javascript:void(0);" onclick="testByName();">按照 name
    获取元素</a>
<a href="javascript:void(0);" onclick="testByTagName();">按照
    标签名获取元素</a>
<a href="javascript:void(0);" onclick="testByClass();">按照
    class 获取元素</a>




</body>
<script type="text/javascript">
    //1.按照 id 获取元素

//返回单个对象,如果出现多个同名Id,则以第一个id的元素为准
        function testById() {
            var p = document.getElementById("p1");
            console.log(p);
            console.log(p.innerHTML); //表示获取元素开始标签和结束标签  之间的 html 结构

            console.log(p.innerText); //表示获取标签之间的普通文本
        }

        //2.按照 name 获取元素
        function testByName() {
//对象数组
            var ho = document.getElementsByName("hobby");
            console.log(ho);
            for (var i = 0; i <= ho.length - 1; i++) {
                console.log(ho[i].value);
            }
        }

        //3根据标签名获取 dom 对象数组
        function testByTagName() {
//对象数组
            var inputArr = document.getElementsByTagName("input");
            for (var i = 0; i < inputArr.length; i++) {
                if (inputArr[i].type == "text") {
                    console.log("text 类型");
                    console.log(inputArr[i].value);
                } else if (inputArr[i].type == "checkbox") {
                    if (inputArr[i].checked) {
                        console.log(inputArr[i].value);
                    }
                }
            }
        }

        //4.根据样式名获取 dom 对象数组
        function testByClass() {
//对象数组
            var ps = document.getElementsByClassName("para");
            console.log(ps[1].innerHTML);
            ps[1].innerHTML += "这是一段新的文本";
        }


    

    // 5.测试按照标签名获取元素
    function testByTagName() {
        var inputs = document.getElementsByTagName("input");
        console.log(inputs.length);

        // 定义变量,接收被选中的复选框的值
        var cks = "";

        // 获取元素的类型 (input中有text、button、radio、checkbox等)
        for (var i = 0; i < inputs.length; i++) {

            var ty = inputs[i].type;
            console.log(ty);
            if (ty == "text") { // 获取文本框
                // 给文本赋值
                inputs[i].value = "admin";

            } else if (ty == "checkbox") { // 获取复选框
                //console.log(inputs[i].checked);
                // 判断复选框是否被选中
                if (inputs[i].checked) {
                    cks += inputs[i].value + ",";
                }
            }
        }
        console.log(cks);
        // 截取字符串
        cks = cks.substring(0,cks.length -1);
        console.log(cks);

    }

</script>
</html>


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

推荐阅读更多精彩内容

  • 事件流 JavaScript与HTML之间的交互是通过事件实现的。事件,就是文档或浏览器窗口中发生的一些特定的交互...
    DHFE阅读 820评论 0 3
  • JavaScript 与 HTML 之间的交互是通过事件实现的。事件,就是文档或浏览器窗口中发生的一些特定的交互瞬...
    LemonnYan阅读 673评论 0 4
  • JavaScript 程序采用了异步事件驱动编程模型。在这种程序设计风格下,当文档、浏览器、元素或与之相关的对象发...
    劼哥stone阅读 1,250评论 3 11
  • 概要 64学时 3.5学分 章节安排 电子商务网站概况 HTML5+CSS3 JavaScript Node 电子...
    阿啊阿吖丁阅读 9,072评论 0 3
  • 声明:本文来源于http://www.webzsky.com/?p=731我只是在这里作为自己的学习笔记整理一下(...
    angryyan阅读 6,940评论 1 6