第1章.基础篇(上)

Abstract:文档树、节点操作、属性操作、样式操作、事件

DOM (Document Object Model) - 文档对象模型

以对象的方式来表示对应的html,它有一系列的规范

i.e.

在浏览器中,DOM是通过JS实现的。

DOM:

DOM Core:核心结构、API的定义

DOM HTML: 定义HTML如何转化成对象(HTML对应的对象)-- 操作节点

DOM Style:样式转换成对象 -- 操作样式

DOM Event:事件对象的模型 -- 响应用户的操作

文档树

HTML -> DOM树

节点遍历

node.parentNode

.firstChild

.lastChild

.previousSibling

.nextSibling

.firstElementChild

.lastElementChild

.nextElementSibling

.previousElementSibling

i.e.

p.parentNode是body

p.firstChild是hello,

p.firstElementChild是span

p.lastElementChild是img

p.lastChild是img

p.previousSibling没有,则返回null

p.nextSibling是div

节点类型:

ELEMENT_NODE:元素节点 (如上body, p, div, span, img)

TEXT_NODE:文本节点(如上hello,, 微专业, mooc)

COMMENT_NODE

DOCUMENT_TYPE_NODE

课堂交流:如何实现浏览器兼容版的element.child

element.children能够获取元素的元素子节点,但是低版本的ie不支持,如何在低版本的ie上兼容类似的功能。

http://www.jianshu.com/p/b7e111015c48

节点操作

Abstract: getElementById, getElementsByClassName, getElementsByTagName, querySelector(All), createElement, innerText, appendChild, insertBefore, removeChild, innerHTML

浏览器读取HTML渲染出页面结构以后,还可以通过JS改变页面的结构

获取节点:

通过节点关系可以获取节点(父子关系、兄弟关系)

缺点:可维护性差,如果一个节点的位置发生了变化,则关系也可能会被打乱

所以,一般使用接口来获取节点(获得的是节点对象:

getElementById:

element = document.getElementById(id):id在document中是唯一标识

getElementsByTagName:

collection = element.getElementsByTagName(tagName):通过元素来调用来获取元素内的节点

若tagName为"*", 则会获取指定元素element包含的所有的后代元素节点

注:collection是动态的集合

getElementsByClassName:

collection = element.getElementsByClassName(className)

通过空格分割,可以指定多个类名(无序),获取同时具有多个类名的元素

但是IE 6/7/8不兼容getElementsByClassName

function getElementsByClassName(element, classNames) {
if (element.getElementsByClassName) {
// 特性侦测,如果兼容则优先使用W3C规范的方式
return element.getElementsByClassName(classNames);
} else {
var elements = element.getElementsByTagName("*"); // 所有后代元素
var result = [];
var element,
classNameStr,
flag;
classNames = classNames.split(' ');
for (var i = 0; element = elements[i]; i++) {
classNameStr = ' ' + element.className + ' ';
flag = true;
for (var j = 0, className; className = classNames[j]; j++) {
if (classNameStr.indexOf(' ' + className + ' ') == -1) {
flag = false;
break;
}
}
if (flag) {
result.push(element);
}
}
return result;
}
}

querySelector:

element = element.querySelector(selector)

返回第一个符合的元素

querySelectorAll:

list = element.querySelectorAll(selector)

i.e.

<div id="users">
<h2>....</h2>
<ul>
<li class="user">Satoshi</li>
<li class="user">春来草青</li>
<li class="user last">Kash</li>
</ul>
</div>

var users = document.querySelector(#users"); // 获取到元素div#users

users.querySelectorAll(".user"); // 获取到 [ li.user  li.user  li.user.last ]

document.querySelectorAll("#users .user"); // 获取到同上 [ li.user  li.user  li.user.last ]

注:list和collection不同之处:list静态的,获取到的结果之后就不会自动同步改变了;而collection是动态的

IE6/7不兼容,IE 8部分兼容

若有如下场景:

想要在<ul> ... </ul>的末尾处增加一个<li>节点,应该怎么做

<ul>
<li>...</li>
...
<li class="user">
<img src="lf.jpg">
<a href="/user/lf">lifeng</a>
</li>
</ul>

1. 创建li节点;设置li节点的class属性;插入li节点

2. 创建img节点;设置img节点的src属性;插入img节点

3. 创建a节点;设置a节点的hrf属性;设置a节点的内容;插入a节点

var li = document.createElement("li");
li.className = 'user';
ul.appendChild(li);
var img = document.createElement("img");
img.src = 'xxx.jpg';
li.appendChild(img);
var a = document.createElement("a");
a.href = '/user/xxx';
a.innerText = "lifeng";
li.appendChild(a);

创建节点

element = document.createElement(tagName);

i.e. var li = document.createElement("li");

修改节点

element.textContent:表示节点及其后代节点的文本内容,但是IE9不支持

i.e. a.textContent = "lifeng";

innerText:不规范,但是经常使用(Firefox不支持)(几乎和textContext一模一样)

i.e. a.innerText = "lifeng";

如果要让Firefox兼容的话(使用textContent)

if(!('innerText' in document.body)) {  // 特性侦测
HTMLElement.prototype._defineGetter_("innerText", function() {
return this.textContent;
});
HTMLElement.prototype._defineSetter_("innerText", function(s) {
return this.textContent = s;
});
}

插入节点

var achild = element.appendChild(achild); // 在element元素内的末尾追加achild节点

i.e. ul.appendChild("li");

var achild = element.insertBefore(achild, referenceChild); // 在referenceChild元素之前插入achild节点

i.e. users.insertBefore(li, ul.firstChild);

删除节点

var child = element.removeChild(child);

i.e. user.parentNode.removeChild(user);

innerHTML:节点的HTML内容

刚才的例子中,为了添加一个lifeng的<li>节点需要那么长的代码,可以使用innerHTML来提高效率

i.e. 设已经添加了一个li节点在ul的末尾;

li.innerHTML = '<img src="xxx.jpg">\

<a href="/user/xxx">lifeng</a>';

li.innerHTML = ""; // 起到删除所有子节点的作用

那可以使用 li.innerHTML += "<li>.......</li>"; 来实现吗?

可以,但是,相当于重新设置了HTML的内容,之前修改过/添加了的事件/样式/状态就会被清除 (覆盖)

innerHTML的问题:内存泄露、安全问题

i.e. 安全问题:利用innerHTML运行代码

var userName = '</a><a onclick="alert(\"我是黑客\");" href="#">lifeng';
li.innerHTML = '<img src="xxx.jpg">\
<a href="/user/xxx/">' + userName + '</a>';

建议仅用于创建新节点

属性操作

实例:登录框的登陆按钮在点击一次后为了避免重复提交会修改按钮的disabled属性让其不可点击

每个HTML attribute都可以对应一个DOM property,修改DOM property就能实现对HMLT attribute的修改

<div>
<label for="userName">用户名:</label>
<input id="userName" type="text" class="u-txt">
</div>

i.e. 上例中对应的DOM property为:label.htmlFor="userName"; input.id="userName"; input.type="text"; input.className="u-txt"(因为for和class是关键字)

三种方法进行属性操作:属性访问器、get/setAttribute、自定义属性dataset

property accessor:

i.e. input.className;  // "u-txt"

input["id"];  // "userName"

input.value = 'www@163.com'; // 给input增加一个value属性并赋值

转换的类型:

(Boolean类型的变量除非设置成false,否则不论是空还是0都表示true)

转换过的为实用对象

优缺点:通用性差--名字异常;扩展性差--每增加一个html属性就需要对应一个DOM属性;优点:获得的是一个实用对象

set/getAttribute:

var attribute = element.getAttribute(attributeName); // 读

element.setAttribute(attributeName, value);  // 写

i.e. input.getAttribute("class");  // "u-txt"

input.setAttribute("value", "www@163.com");

input.setAttribute("disabled", "");  // 设置disabled属性为true(前面提到了,只要属性出现了而且不是false,那么就是true)

转换的类型都为String,获得的是属性字符串

优缺点:只能处理字符串,推荐如果是纯字符串操作就使用get/setAttribute()

dataset:自定义属性

HTMLElement.dataset

data-*属性集

一般用于元素上保存数据(自定义的数据属性)

<div id="user" data-id="123456" data-account-name="wwq" data-name="smith" data-email="wwq123@163.com" data-mobile="123123">wwq</div>

属性名:将"data-"去掉,如果有连接符,会以大写开头表示

i.e. 鼠标悬停在姓名上时会显示对应详细信息的表格

<body>
<ul>
<li data-id="123456" data-account-name="wwq"
data-name="魏文庆" data-email="wwq123@163.com"
data-mobile="13524543878">wwq</li>
<li data-id="123457" data-account-name="cjf"
data-name="蔡剑飞" data-email="cjf123@163.com"
data-mobile="13968789868">cjf</li>
</ul>
<div id="card" style="display:none">
<!-- 将空卡片隐藏 -->
<table>
<caption id="accountName"></caption>
<tr><th>姓名:</th><td id="name"></td></tr>
<tr><th>邮箱:</th><td id="email"></td></tr>
<tr><th>手机:</th><td id="mobile"></td></tr>
</table> </div>
<script>
function $(id){
return document.getElementById(id);
} var lis = document.getElementsByTagName('li');
for(var i = 0, li;li = lis[i]; i++){
li.onmouseenter = function(event){
event = event || window.event;
var user = event.target|| event.srcElement;
var data = user.dataset; // 插入相关数据
$('accountName').innerText = data.accountName;
$('name').innerText = data.name;
$('email').innerText = data.email;
$('mobile').innerText = data.mobile;
// 显示卡片
$('card').style.display = 'block';
}; li.onmouseleave = function(event){
$('card').style.display = 'none';
};
} </script>
</body>

dataset在低版本浏览器中不兼容,怎么实现?

function dataset(element) { // my own version(haven't checked yet)
if (element.dataset) {
// check whether the original version od dataset is available
return element.dataset;
} else {
var data = [];
for (var i = 0; i < element.attributes.length; i++) {
// traverse all the attributes element has
if (/^data-/.test(element.attributes[i].nodeName) {
// attribute_name starts with "data-"
data[element.attributes[i].nodeName.replace("data-","")] = element.attributes[i].nodeValue;
}
}
return data;
}
}

样式操作

样例:

格式不正确

QQ空间换皮肤等

-- 可通过JS动态修改样式

CSS --> DOM

<head>
<link rel="stylesheet" href="base.css">
<style>
body {margin: 30;}
p {color: #aaa; line-height: 20px; }
</style>
</head>
<body>
<p style="color:red;"> paragraph</p>
</body>

3中css的引用:

<link> 对应的为element.sheet

<style> 对应的为element.sheet

style="" 对应的为element.style

整张页面的所有样式对应的为document.styleSheets

i.e. element.sheet:

element.sheet.cssRules : 对应body{...} 和 p{...}

element.sheet.cssRules[1] : 对应p{...}

element.sheet.cssRules[1].selectorText : 对应选择器p

element.sheet.cssRules[1].style : 属于类CSSStyleDeclaration的对象。对应p{...}中的css声明color:#aaa; line-height:20px;

element.sheet.cssRules[1].style.lineHeight : 对应属性值20px

element.style:属于CSSStyleDeclaration类的对象,遇上相同,对应css声明color:red;

element.style.color : 对应red

对样式的增删查改:

更新样式:

element.style.borderColor = 'red';

element.style.color = 'red';

-- 更新一个属性需要一条语句,而且不是css格式

更好的方式:cssText

i.e. element.style.cssText = 'border-color:red; color:red;';

-- 一条语句可以设置一个元素,符合css格式

但是:样式与逻辑混合

更好的方式:更新class -- 开发中使用的方法

首先,在css样式中增加样式 .invalid { border-color:red; color:red; }

在JS中输入框对象处:element.className += 'invalid';

但是如果要一次性修改批量元素的样式呢,比如上述的QQ空间换肤实例:可以使用更换样式表

原版本 <link rel="stylesheet" href="style.css">

可以拆分为两个样式表 base.css 和 skin.spring.css

要换肤时,比如换成夏天皮肤,则将skin.spring.css 换成 skin.summer.css即可

<head>
<title>换肤 - 更新样式</title>
<link rel="stylesheet" href="base.css">
<link id="skin" rel="stylesheet" href="skin.spring.css">
</head>
<body>
<div class="m-tw clearfix">
<div class="u-img">
<a href="#"><img src="zhm.jpg" alt=""></a>
</div>
<div class="txt">
<h3><a href="#">张惠妹</a></h3>
<p>亞洲國寶級傳奇天后「 a MEI」我是a MEI,一個你認識很久,卻認識不完的女人。</p>
</div>
</div>
<button id="change">换肤</button> <script src="../util.js"></script>
<script>
Util.addEventListener($('change'), 'click', changeSkin); function changeSkin(){
$('skin').href = "skin.summer.css";
} </script>
</body>
/* skin.spring.css */
body{background-color: #d6e6c6;}
.m-tw .u-img{border-color: #6e9d41;}
.m-tw p{color: #367701;}
.m-tw h3{background-color: #6e9d41;}
.m-tw h3 a, .m-tw h3 a:hover{color: #fff;}
/* skin.summer.css */
body{background-color: #fefaf7;}
.m-tw .u-img{border-color: #a84c5b;}
.m-tw p{color: #6d3e48;}
.m-tw h3{background-color: #a84c5b;}
.m-tw h3 a, .m-tw h3 a:hover{color: #fff;}

相似的,也可以进行删除样式表、添加样式表等操作

获取样式:

i.e. 有一<input type="text">

element.style.color;  // ""

字体是黑色,为什么获取到的为空呢?因为element.style对应的为内嵌样式表,确实为空

若是<input type="text" style="color:red"> 则可获取到"red"

实际上有三种样式设置方式,而且style获取到的不一定是实际样式,所以不采取上述方法获取样式属性

window.getComputedStyle()

var style = window.getComputedStyle(element [, pseudoElt]);

// 返回值的类型也是CSSStyleDeclaration,但是是只读的,包含了所有的属性名和属性值的键值对

i.e. window.getComputedStyle(input).color;  // "rgb(0,0,0)"

IE9以下不兼容,可以使用element.currentStyle(不规范)

http://web.zhydaxq.com/2017/04/14/%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E6%B5%8F%E8%A7%88%E5%99%A8%E5%85%BC%E5%AE%B9%E7%89%88%E7%9A%84window-getcomputedstyle/

事件

什么是DOM事件?当我们点击一个DOM元素时,或键盘按下一个键,或在输入框中输入内容,或页面加载完成时,都是DOM事件

事件流:

DOM事件的处理过程 http://www.w3.org/TR/uievents/#dom-event-architecture

i.e.

当点击了a标签时,就会产生一个DOM的click事件,事件的处理过程:

capture phase:从DOM树的根节点开始捕获直到事件节点的父元素:window->document->html->body->div->p

target phase:事件的触发过程 从父节点p到事件发生所在节点a

bubble phase:冒泡过程:从事件所在节点的父节点开始,冒泡到最顶层的window对象

(IE低版本没有捕获过程;而且也不是所有事件都有这三个过程,比如页面load事件并没有冒泡过程)

事件注册与触发

注册事件

eventTarget.addEventListener(type, listener [,useCapture])

type: 事件类型;listener:事件处理函数;useCapture:是否为捕获过程(默认处理的是冒泡过程)

var element = document.getElementById('div1');
var clickHandler = function(event) {
// TO-DO
}
element.addEventListener('click', clickHandler, false); // 默认为false

还有一种方法进行注册:

element.onclick = clickHandler;

缺陷:这种注册方式下的事件处理函数只能有一个,但很多情况下需要注册多个事件处理函数

取消事件注册

eventTarget.removeEventListener(type, listener [,useCapture])

i.e. element.removeEventListener('click', clickHandler, false);

或者通过 element.onclick = null; 来取消注册

事件触发:使用代码来触发事件(不包括点击之类的触发)

eventTarget.dispatchEvent(type);  // type:事件类型;就能触发相应类型的DOM事件了

i.e. elem.dispatchEvent('click');  // 使用代码触发elem元素的单击事件

低版本浏览器的兼容:IE6/7/8没有采用这些W3C标准

没有capture捕获阶段,只能处理冒泡阶段

事件注册与取消:attchEvent/detachEvent

事件触发:fireEvent(e)

var addEvent = document.addEventListener ?
function(elem, type, listener, useCapture) {
elem.addEventListener(type, listener, useCapture);
} :
function(elem, type, listener, useCapture) {
elem.attachEvent('on' + type, listener);
}; // 区别:1. 事件类型前缀了'on',2. 没有useCapture参数 var delEvent = document.removeEventListener ?
function(elem, type, listener, useCapture) {
elem.removeEventListener(type, listener, useCapture);
} :
function(elem, type, listener, useCapture) {
elem.detachEvent('on' + type, listener);
};

事件对象

当事件触发时,会调用事件处理函数,此时需要事件状态的信息,事件对象就包含了这些信息。引擎在调用处理函数时会传入事件对象

i.e. 上例elem.addEventListener('click', clickHandler, false);中

触发click事件时会调用clickHandler函数,执行时会传入event对象,即事件对象(var clickHandler = function(event) {...})

可能该事件对象包含了鼠标位置等信息

在IE的低版本里有一些不同,事件的event对象并不是直接通过函数传入的,而是放在window对象中

兼容版本:

var elem = document.getElementById('div1');
var clickHandler = function(event) {
event = event || window.event;
// TO-DO
}

事件对象的属性和方法:

不同分类的事件在不同场景下的事件对象都有可能不同

通用的属性和方法:

属性:

type: 事件类型,如click

target(IE低版本为srcElement): 事件触发的节点,如a元素

currentTarget: 当前处理事件的节点(处理一个事件时,不一定要把事件注册在target上,可以注册在父节点(由于冒泡))

只有事件处于目标阶段时,currentTarget和target的值才是肯定相同的

方法:

stopPropagation: 阻止传播,使事件的冒泡停止

preventDefault: 阻止默认行为

默认行为:比如双击文字时文字会被选中,比如单击连接时连接会被打开

stopImmediatePropagation: 阻止冒泡

i.e.

event.stopPropagation() (W3C): 阻止冒泡到父节点

event.cancelBubble=true (IE低版本)

event.stopImmediatePropagation() (W3C): 两个结果:1. stopPropagation(); 2. 所有该节点的后续事件也不会触发

event.preventDefault() (W3C)

event.returnValue=false (IE低版本)

事件分类 http://www.w3.org/TR/uievents/

Abstract: 事件分类及继承关系;鼠标事件类型、鼠标事件对象、鼠标事件举例;键盘、输入、焦点事件类型、事件对象、事件举例

MouseEvent:

事件类型:

click:单击

dbclick:双击

mousedown:按下鼠标

mousemove:鼠标移动

mouseout:鼠标从某元素上移开

mouseover:鼠标在某元素上(若鼠标在元素子元素上,也是可行的--可冒泡)

mouseup:释放鼠标

mouseenter:鼠标进入元素(只有鼠标在该元素上时,不可冒泡)

mouseleave:鼠标离开元素(不可冒泡,与mouseout(可冒泡)的区别和mouseenter和mouseover的区别一样)

属性:

clientX, clientY:到页面的左上的距离

screenX, screenY:到屏幕的左上的距离

ctrlKey, shiftKey, altKey, metaKey:事件触发时若键按下则为true

button:值为0/1/2,表示按下的是鼠标的左键/中间键/右键

顺序:

i.e. 鼠标从元素A外面移动到元素A上面,再划出去的过程中:

mousemove -> mouseover(A) -> mouseenter(A) -> mousemove -> mouseout(A) -> mouseleave(A)

(mousemove一直在触发,触发间隔由浏览器决定)

i.e. 点击元素:

mousedown -> [mousemove] -> mouseup -> click

(click事件是在鼠标松开之后才触发的)

实例. 拖拽div

<div id="div1"></div> 
<style type="text/css">
#div1{ position:absolute; top:; left:;
border:1px solid #000;
width:100px; height:100px;
}
</style> 
var elem = document.getElementById("div1");
var clientX, clientY, moving;
var mouseDownHandler = function (event) {
// 鼠标按下
event = event || window.event;
clientX = event.clientX;
clientY = event.clientY;
moving = !0; // 点下去后设置moving为true
}
var mouseMoveHandler = function(event) {
// 鼠标移动(drag的移动过程)
if (!moving) return; // 鼠标还未down
event = event || window.event;
var newClientX = event.clientX,
newClientY = event.clientY;
var left = parseInt(elem.style.left) || 0,
top = parseInt(elem.style.top) || 0;
elem.style.left = left + (newClientX - clientX) +'px'; // 用offset量来确定div的移动
elem.style.top = top + (newClientY - clientY) +'px';
clientX = newClientX; // 更新clientX和clientY,用于下次move触发
clientY = newClientY;
}
var mouseUpHandler = function (event) {
moving = !1;
}
addEvent(elem, 'mousedown', mouseDownHandler);
addEvent(elem, 'mousemove', mouseMoveHandler);
addEvent(elem, 'mouseup', mouseUpHandler); 

WheelEvent:从MouseEvent继承

事件类型只有一种 wheel

属性:

deltaMode:指定delta值的单位

deltaX、deltaY、deltaZ:在X/Y/Z方向上的偏移量

FocusEvent:元素获取或失去焦点的时候触发(比如点击输入框出现光标/点击页面其他地方取消输入框可输入状态)

事件类型:

blur:元素失去焦点时

focus:元素获得焦点时

focusin:元素即将获得焦点时(获得焦点之前)

focusout:元素即将失去焦点时(失去焦点之前)

属性:

relatedTarget:当一个元素失去焦点时,另一个元素就会获得焦点,blur/focusout中获得焦点的元素就是relatedTarget

当一个元素获得焦点时,另一个失去焦点的元素就是focus/focusin里面的relatedTarget

InputEvent:处理输入事件

事件类型:

beforeinput:输入在页面上还不能看到时

input:当输入框里的内容已经有输入内容时(继续输入时也会不断触发input事件)

在IE低版本中没有input事件,使用onpropertychange

KeyboardEvent:处理键盘事件

事件类型:

keydown:按下键

keyup:松开键

属性:

key:字符串,按下的按键

code:字符串,按键对应码

ctrlKey/shiftKey/altKey/metaKey:标识是否被按下

repeat:一个键持续按着

以上为W3C,以下为常用非标准

keyCode、charCode、which:用于获取按键对应的ASCII码,实际编程用这些ASCII码来判断

Event 最基本的事件:

事件类型:

load:代表元素 (如window, image, iframe等依赖网络加载的元素) 加载完成

unload:与load对应,代表元素退出时(被关闭)

error:加载错误,比如讲img的src路径写错了

select:比如input/textarea输入框被选择时

abort:window/image等元素正在加载时,按下了esc

按对象来解释这些事件:

window:

load:页面的所有请求都完成了,所有需要加载的元素都加载了的时候

unload:当关闭当前页面时

error:浏览器加载当前页面异常

abort:退出时

image:

load:图片按照src地址通过网络连接加载完成时

error:图片加载异常

abort:图片加载时,按下了esc等中断图片的加载

<!-- 通常会这么写 -->
<image alt="photo" src=".../photo.jpg" onerror="this.src='...default.jpg'"/>

UIEvent:

事件类型:

resize:修改浏览器或iframe窗体大小时,

scroll:页面发生滚动时触发。若滚动是在一个元素上触发的,则会冒泡;如果是系统(document)滚动条,则不会冒泡

事件代理

场景:一个ul中有很多li,要对这些li都注册一个click事件,需要一个一个注册吗?

-- 直接将click事件注册到ul上即可,因为click事件支持冒泡:li上的事件最终肯定会冒泡到ul上,只需在ul上处理所有li的事件即可

-- 事件代理:将事件注册到元素的父节点上

优点:1. 不用注册那么多的事件;2. 内存分配少

缺点:如果把事件全放入父元素,事件管理起来会很复杂(比如将所有事件都注册到window对象上,事件处理函数会很复杂)

(数据通信、数据存储、动画、音频与视频、canvas、BOM、表单操作、列表操作见基础篇(下))

前端开发工程师 - 03.DOM编程艺术 - 第1章.基础篇(上)的更多相关文章

  1. 前端开发工程师 - 03.DOM编程艺术 - 第1章.基础篇(下)

    第1章.基础篇(下) Abstract: 数据通信.数据存储.动画.音频与视频.canvas.BOM.表单操作.列表操作 数据通信(HTTP协议) HTTP事务: 客户端向服务器端发送HTTP请求报文 ...

  2. 前端开发工程师 - 03.DOM编程艺术 - 期末考试

    期末考试客观题 返回    倒计时: 01:24 1 单选(2分) 以下选项中不是节点类型的是 A. COMMENT_NODE B. DOCUMENT_NODE C. BODY_NODE D. E ...

  3. JavaScript取消默认控件并添加新控件(DOM编程艺术第11章)

    这一章实现的这个功能我研究了好久,这个思路我感觉已经是现在的我要膜拜的了,我感觉我的逻辑还是有些问题. 第一个问题:vid.height与vid.videoHeight vid.height = vi ...

  4. JavaScript DOM编程艺术第四章 — JavaScript图片库案例研究

    这一章通过JavaScript图片库案例,学习了一些DOM属性. HTML代码 <!DOCTYPE html> <html> <head> <meta cha ...

  5. javascript DOM编程艺术 第10章问题记录

    为什么moveElement函数调用时,必须加字符串的拼接符 var repeat = "moveElement('"+elementID+"',"+final ...

  6. 《DOM编程艺术》读书笔记<概述>

    作为一名前端开发工程师,学习的过程中总少不了各种各样的书籍,作为新手如何在众多书籍中选到适合自己的呢,我们今天先来谈谈<DOM编程艺术>这本书. 其实呢大部分书都是好书,就像LOL中大部分 ...

  7. JavaScript DOM编程艺术读后感(1)—— 平稳退化

    最近,在读<JavaScript DOM编程艺术(第二版)>这本书,想着将自己的读后感记录下来,作为记忆吧. 其实我并不是最近才刚开始读这本书的,我读了有一段时间了.我是一名web前端开发 ...

  8. 前端开发工程师 - 06.Mini项目实战 - 项目简介

    第6章--Mini项目实战 项目简介 Mini项目简介-Ego社区开发 回顾: 页面制作 页面架构 JavaScript程序设计 DOM编程艺术 产品前端架构 实践课Mini项目--Ego: 主题:漫 ...

  9. JavaScript DOM编程艺术(第2版)的简单总结

    介绍 JavaScript DOM编程艺术(第2版)主要讲述了 JavaScript.DOM 和 HTML5 的基础知识,着重讲述了 DOM 编程,并通过几个实例演示了具有专业水准的网页开发. 下面介 ...

随机推荐

  1. Python 学习笔记(十一)Python语句(二)

    For 循环语句 基础知识 for循环可以遍历任何序列的项目,如一个列表或者一个字符串. 语法: for 循环规则: do sth >>> for i in "python ...

  2. Jumpserver堡垒机搭建(脚本自动化)

    #!/bin/bash # coding: utf- # Copyright (c) set -e #返回值为非0时,退出脚本 echo "0. 系统的一些配置" setenfor ...

  3. 一点一点看JDK源码(三)java.util.ArrayList 前偏

    一点一点看JDK源码(三)java.util.ArrayList liuyuhang原创,未经允许禁止转载 本文举例使用的是JDK8的API 目录:一点一点看JDK源码(〇) 1.综述 ArrayLi ...

  4. direct path write 等待事件导致数据库hang

    同事反应十几分钟前数据库好像挂起了一会,让我排查数据库是否存在什么问题. 第一反应看当前数据库还是否有什么等待事件,结果有direct path write等待事件. 于是抓了问题时间段20分钟的AS ...

  5. SHELL脚本简单的赋值与递增

    Count=`expr $Count + 1`;#可以在各种shell执行,其他类C的写法只能在指定的bash版本执行; 赋值不能带$, 带$相当于字符串常量了;执行脚本参考如下 #!/bin/sh ...

  6. Tomcat性能监控

    Tomcat性能监控工具很多,这里介绍两种1.JMeter 2.probe,使用这两种工具都需要在tomcat的安装目录/conf/tomcat-users.xml添加 <tomcat-user ...

  7. CSS动画实例

    上一篇讲过css动画transform transition的语法,这一节展示自己做的几个小例子加深印象 1. 线条动画效果 代码:最外层div包含2个小的div : a和b.   a有左右边框(高度 ...

  8. ethereum(以太坊)(实例)--"简单的公开竞拍"

    说真的,刚开始接触这个竞拍案例--“简单的公开竞拍”,我就抱着简单的心态去查看这个实例,但是自我感觉并不简单.应该是我实力不到家的原因吧!!!233333...不过经过大半天的努力,自己理解完之后,觉 ...

  9. 使用Letsencrypt做SSL certificate

    为什么要使用Letsencrypt做SSL certificate? 最简单直接的原因是免费.但是免费存在是否靠谱的问题,尤其是对安全要求比较高的网站,需要考虑使用letsencrypt的安全性是否符 ...

  10. 【Spark】源码分析之SparkContext

    一.概述 SaprkContext非常重要,是Spark提交任务到集群的入口 SparkContext中没有main方法,在SparkContext主构造器中,主要做一下四件事情: 1. 调用crea ...