灏天阁

DOM 的元素实例

· Yin灏

设置焦点跳转至特定元素实例上的快捷键

<a href="#a01" accessKey="1">To a01</a>
<a href="#a02" accessKey="2">To a02</a>
<a href="#a03">To a03</a>
<a href="#a04">To a04</a>
<a href="#a05">To a05</a>
<br>
<a href="http://www.tup.tsinghua.edu.cn" target="new" accessKey="6">To Official Website</a>
<p></p>

<a name="a01">a01</a>
<div id="div01">
  <input type="text" id="username" size="8" placeholder="username...">
  <input type="password" id="password" size="8" placeholder="password...">
  <br>
</div>

<a name="a02">a02</a>
<div id="div02">
  ...
</div>

<a name="a03">a03</a>
<div id="div03">
  ...
</div>

<a name="a03">a03</a>
<div id="div03">
  ...
</div>

<a name="a04">a04</a>
<div id="div04">
  ...
</div>

<a name="a05">a05</a>
<div id="div05">
  ...
</div>
a {
  display: inline-block;
  margin: 5px;
}

[id^=div] {
  display: block;
  padding: 10px;
  height: 500px;
}

#div01 {
  background-color: Gold
}

#div02 {
  background-color: GreenYellow
}

#div03 {
  background-color: YellowGreen
}

#div04 {
  background-color: RoyalBlue
}

#div05 {
  background-color: Chocolate
}
let links = document.links;

console.log(links.length);

// 设置快捷键 alt + 3
links[2].accessKey = '3';
// 设置快捷键 alt + 4
links[3].accessKey = '4';
// 设置快捷键 alt + 5
links[4].accessKey = '5';


username.accesskey = 'u';

password.accesskey = 'p';

创建特定元素实例的动画效果

let frame01 = {
  transform: 'translateY(0px)'
}

let frame02 = {
  transform: 'translateY(20px)'
}

let keyframes = [
  frame01,
  frame02
];

let options = {
  duration: 1000,
  iterations: 4,
  direction: 'alternate',
  easing: 'ease-in-out'
}

div01.animate(
  keyframes,
  options
);

添加新元素实例和访问特定元素实例的所有属性

let ref = document.createElement('h1');

ref.innerHTML = 'Box World';

with(ref.style) {
  color = 'RoyalBlue';
  textDecoration = 'underline';
}


document.body.appendChild(ref);

ref = document.createElement('div');
ref.innerHTML = 'Be diligent';
ref.id = 'big_block';

with(ref.style) {
  color = 'Gold';
  backgroundColor = 'RoyalBlue';
  width = height = '110px';
  textAlign = 'center';
  margin = 'auto';
  padding = '5px'
}

document.body.appendChild(ref);

ref = document.createElement('h3');
ref.innerHTML = 'Great';
ref.id = 'small_block';

with(ref.style) {
  color = 'GreenYellow';
  backgroundColor = 'ForestGreen';
  width = height = '60px';
  textAlign = 'center';
  marign = '10px auto';
  borderRadius = '10px';
  padding = '5px';
}

big_block.appendChild(ref);

console.log(small_block.attributes); // NamedNodeMap {0: id, 1: style, id: id, style: style, length: 2}
console.log(small_block.attributes.length); // 2

console.log(small_block.attributes[0]); // id
console.log(small_block.attributes[0].nodeValue); // 'small_block'

console.log(small_block.attributes[1]); // style="color: greenyellow; background-color: forestgreen; height: 60px; width: 60px; text-align: center; border-radius: 10px; padding: 5px;"
console.log(small_block.attributes[1].nodeValue); // color: greenyellow; background-color: forestgreen; height: 60px; width: 60px; text-align: center; border-radius: 10px; padding: 5px;

使得特定元素实例失去和获取焦点

<a href="#">Link 1</a>
<a href="#">Link 2</a>
<a href="#">Link 3</a>
<a href="#">Link 4</a>
<a href="#">Link 5</a>

<p></p>

<input type="text">
<input type="text">
<input type="text">

<p></p>

<button type="button">Button 1</button>
<button type="button">Button 2</button>
<button type="button">Button 3</button>
a, [type=text], [type=button] {
  margin: 5px;
}
let refs = document.querySelectorAll('a, [type=text], button');

let index = 0;

console.log(refs.length); // 11

let interval_no = setInterval(focus_next, 500);

function focus_next() {
  refs[index].focus();
  index = index < refs.length - 1 ? index + 1 : 0;
}

setTimeout(blur_all, 7000);

function blur_all() {
  clearInterval(interval_no);
  refs[index - 1].blur();
}

获取子节点或子元素实例

/**
 * .childNodes 访问特定元素实例的子节点实例
 * .children 访问特定元素的子元素实例
 * .childElementCount 获取特定元素实例内的子元素实例的个数
 */

with(console) {
  log(document.body.childElementCount); // 7
  log(div01.childElementCount); // 3
  log(div02.childElementCount); // 3

  log(document.body.childNodes); // NodeList(18) [text, comment, text, h1, text, div#div01, text, div#div02, text, ol, text, comment, text, script, text, script, text, script]
  log(div01.childNodes); // NodeList(7) [text, a, text, a, text, a, text]
  log(div02.childNodes); // NodeList(7) [text, li, text, li, text, li, text]

  log(document.body.children); // HTMLCollection(7) [h1, div#div01, div#div02, ol, script, script, script, div01: div#div01, div02: div#div02]
  log(div01.children); // HTMLCollection(3) [a, a, a]
  log(div02.children); // HTMLCollection(3) [li, li, li]

  div01.children[0].style.textDecoration = 'overline';
  div01.children[1].style.textDecoration = 'line-through';
}

访问被应用在特定元素实例的所有 css 类名

div01.className = 'color';
div02.className = 'color size';
div03.className = 'color size alignment';
div04.className = 'color size alignment border';


console.log(div01.className); // color
console.log(div02.className); // color size
console.log(div03.className); // color size alignment
console.log(div04.className); // color size alignment border


div05.className = 'color';
div05.classList.add('size');
div05.classList.add('alignment', 'border');
div05.classList.remove('color', 'size');

console.log(div05.classList.contains('size')); // false
console.log(div05.classList.contains('border')); // true

获取特定元素的尺寸、坐标与可定位的上层元素

/**
 * clientWidth、clientHeight、offsetWidth、offsetHeight 可获取特定元素实例的尺寸相关数据
 * clientLeft、clientTop、offsetLeft、offsetTop 可获取特定元素实例的坐标相关数据
 * offsetParent 可获取可定位的上层元素实例
 */
console.log(div01.clientWidth); // 120  content + padding(不包括 滚动条、边框、外边距margin )
console.log(div01.offsetWidth); // 136  content + padding + border

console.log(div01.clientHeight); // 80  content + padding(不包括 滚动条、边框、外边距margin )
console.log(div01.offsetHeight); // 96  content + padding + border

console.log(div01.clientLeft); // 8 (外边框左侧顶点作为原点,客户区域左侧顶点的 x 坐标为 8)
console.log(div01.offsetLeft); // 892 (浏览器左侧顶点作为原点,边框区域左侧顶点的 x 坐标为 892)

console.log(div01.clientTop); // 8 (外边框左侧顶点作为原点,客户区域左侧顶点的 y 坐标为 8)
console.log(div01.offsetTop); // 50 (浏览器左侧顶点作为原点,边框区域左侧顶点的 y 坐标为 50)


console.log(div01.parentElement.tagName); // BODY
console.log(div01.offsetParent.tagName); // BODY

div01.offsetParent.style.backgroundColor = 'YellowGreen';

判断是否存在特定子元素或可被编辑

<div id="div01">
   <p id="p01">Super</p>
   <a href="#" id="a01">happy time</a>
</div>
div {
  text-align: center;
  color: IndianRed;
  background-color: Pink;
  width: 80px;
  height: 80px;
  margin: 10px;
}

h3 {
  line-height: 1em;
}

a {
  text-decoration: none;
  color: Yellow;
}
console.log(document.body.contains(div01)); // true
console.log(document.body.contains(p01)); // true

console.log(div01.contains(a01)); // true

console.log(p01.contains(a01)); // false

console.log(p01.isContentEditable); // false

p01.contentEditable = true;

访问特定元素实例的文本被书写的方向

<p id="p01">
  To live happily ever after...
</p>
#p01 {
  color: RoyalBlue;
  background-color: Gold;
}
// p01.style.direction = 'rtl';
p01.dir = 'rtl';

返回头尾的子节点实例或子元素实例

Inventory
<div id="div01">
  Fruits
  <p>apple</p>
  <p>banana</p>
  <p>cherry</p>
</div>

<div id="div02">
  Vegetables
  <p>burdock</p>
  <p>cabbage</p>
  <p>spinach</p>
</div>

<span>test</span>
/**
 * firstChild 可返回特定元素实例的第 1 个子节点实例
 * firstElementChild 可返回特定元素实例的第 1 个子元素实例
 * lastChild 可返回特定元素实例的最后 1 个子节点实例
 * lastElementChild 可返回特定元素实例的最后 1 个子元素实例
 */

console.log(document.body.firstChild);

/*
"

    Inventory
"
*/

console.log(document.body.firstElementChild); // <div id="div01"></div>

console.log(div01.firstChild);

/*

"

    Fruits
"
*/
console.log(div01.firstElementChild); // <p>apple</p>

console.log(div01.lastChild); // #text
console.log(div01.lastElementChild); // <p>cherry</p>

访问或删除特定元素实例的特定属性

/**
 * getAttribute() 可获取特定元素实例的特定属性的数据。
 * getAttributeNode() 可获取特定元素实例的特定属性对应的属性节点实例。
 * setAttribute() 可设置特定元素实例的特定属性的数据。
 * setAttributeNode() 可设置特定元素实例特定属性对应的属性节点实例。
 * removeAttribute() 可删除特定元素实例的特定属性。
 * removeAttributeNode() 可删除特定元素实例的特定属性对应的属性节点实例。
 */

console.log(div01.getAttribute('id')); // 'div01'
console.log(div01.getAttributeNode('id')); // id="div01" 属性节点

let a_node = div01.getAttributeNode('id');
console.log(a_node.name); // id
console.log(a_node.value); // div01

a_node = document.createAttribute('title');
a_node.value = 'Author:Francesco';

div01.setAttributeNode(a_node);

console.log(div01.title); // 'Author:Francesco'

div01.setAttribute('align', 'center');
console.log(div01.align); // 'center'

div01.removeAttribute('title'); // 获取到属性名就可以删除
console.log(div01.title); // ''

a_node = div01.getAttributeNode('align');
console.log(a_node); // align="center"

div01.removeAttributeNode(a_node); // 删除一个属性节点

console.log(div01.align);

访问特定元素实例的常见属性的数据

<div id="box01">
   Area one
</div>
<div id="box02">
   Area two
</div>
<div id="box03">
   Area three
</div>
with (console) {
  log(box01.id); // 'box01'
  log(box01.innerHTML);
  /*

    Area one

  */
  log(box01.tagName); // 'DIV'
  log('');

  box02.title = 'This area is optional.';

  // box03.textContent = '3rd area';
  box03.innerHTML = '3rd area';
  box03.style.backgroundColor = 'Gold';
  box03.style.textDecoration = 'underline';

  let nodes = document.getElementsByTagName('div');
  log(nodes.length); // 3
}

判断是否存在任何子节点实例

<select id="list01">
  <option>item 1</option>
  <option>item 2</option>
  <option>item 3</option>
</select>
<ul id="list02">
  <li>item 1</li>
  <li>item 2</li>
  <li>item 3</li>
</ul>
<div id="list03">
  <p id="p01">paragraph 1</p>
  <p id="p02">paragraph 2</p>
  <p id="p03">paragraph 3</p>
  <p id="p04"></p>
  <p id="p05"></p>
</div>
/**
 * hasChildNodes() 判断是否存在任何子节点实例
 */

with(console) {
  log(list01.hasChildNodes()); // true
  log(list02.hasChildNodes()); // true
  log(list03.hasChildNodes()); // true
  log(p01.hasChildNodes()); // true
  log(p04.hasChildNodes()); // false
  log(p05.hasChildNodes()); // false
}

在特定子节点实例之前新增另一个子节点实例

<div id="text">
  <p id="seperator">Default paragraph</p>
</div>
let ref = document.createElement('p');
ref.innerHTML = '1st inserted.';
ref.style.color = 'RoyalBule';
text.appendChild(ref);

ref = document.createElement('p');
ref.innerHTML = '2nd inserted.';
ref.style.color = 'Purple';
// 两个参数:第一参数为 dom 元素,第二个参数为要插入的位置
text.insertBefore(ref, text.children[0]);

ref = document.createElement('p');
ref.innerHTML = '3rd inserted.';
ref.style.color = 'GreenYellow';
text.insertBefore(ref, seperator);

判断两个节点实例的内容是否完全相同

<p>
  Go
  <span>Travelling</span>
</p>
<p>
  Go
  <span>Trip</span>
</p>
<p>
  Go
  <span>Travelling</span>
</p>
/**
 * isEqualNode() 可判断两个特定变量的数据,是否指向同一个内存引用地址的节点实例。
 * isSameNode() 可判断 2 个特定变量的数据所指向的节点实例内容,是否完全相同。
 */

let nodes = document.body.children;
console.log(nodes);

// 所谓完全相同:从两个元素实例的起始语句的位置开始,连细微的1个文字,甚至1个空格字符的相对位置,都没有任何差别。
console.log(nodes[0].isEqualNode(nodes[1])); // false
console.log(nodes[0].isEqualNode(nodes[2])); // true

// 各自占用不用的内存地址
console.log(nodes[0].isSameNode(nodes[1])); // false
console.log(nodes[0].isSameNode(nodes[2])); // false

let p_nodes = document.querySelectorAll('p');

// 不同方式获取的同一元素
console.log(nodes[0].isSameNode(p_nodes[0])); // true
console.log(nodes[1].isSameNode(p_nodes[1])); // true
console.log(nodes[2].isSameNode(p_nodes[2])); // true

返回下一个或上一个兄弟节点实例

<p id="p01">Paragraph 1</p>
<p id="p02">Paragraph 2</p>
<p id="p03">Paragraph 3</p>
<p id="p04">Paragraph 4</p>
<p id="p05">Paragraph 5</p>
/**
 * nextSibling 返回下一个兄弟节点实例
 * previousSibling 返回上一个兄弟节点实例
 */
console.log(p01.nextSibling); // #text
console.log(p01.nextSibling.nextSibling); // <p id="p02">...</p>

console.log(p03.nextElementSibling);

console.log(p05.previousSibling); // #text
console.log(p05.previousSibling.previousSibling); // <p id="p04">...</p>
console.log(p05.previousElementSibling); // <p id="p04">...</p>

返回特定节点实例的相关数据

Sample...
<div id="div01" style="color: RoyalBlue; background-color: Gold;">
  Time is money...
</div>
let node = div01;

console.log(node.nodeName); // 'DIV'
console.log(node.nodeType); // 1
console.log(node.nodeValue); // null

// 返回属性 id 的属性节点实例
node = div01.getAttributeNode('id');
console.log(node); // 'div01'

console.log(node.nodeName); // id
console.log(node.nodeType); // 2
console.log(node.nodeValue); // 'div01'

node = document.body.firstChild;  // 文本节点实例

console.log(node.nodeName); // #text
console.log(node.nodeType); // 3
console.log(node.nodeValue);
/*

    Sample...

*/

合并多个相邻的文本子节点实例

<div id="div01"></div>
let node = document.createTextNode('Happily');
div01.appendChild(node)

node = document.createTextNode('ever');
div01.appendChild(node)

node = document.createTextNode('after');
div01.appendChild(node)

console.log(div01.childNodes); // NodeList(3) [text, text, text]
console.log(div01.childNodes.length); // 3
console.log(div01.childNodes[0]); // 'Happily'
console.log(div01.childNodes[1]); // 'ever'
console.log(div01.childNodes[2]); // 'after'

// 会在 body 元素实例中,将所有相邻的数个文本节点实例,合并成为单个文本节点实例
document.body.normalize();

// 只剩下一个子节点
console.log(div01.childNodes); // NodeList [text]
console.log(div01.childNodes.length); // 1
console.log(div01.childNodes[0]); // Happilyeverafter

返回父节点实例

<div id="div01">
  <p id="p01">
    <a id="a01" href="#">Link 1</a>
  </p>
</div>
/**
 * parentNode 返回父节点实例
 * parentElement 返回父元素实例
 */
with(console) {
  log(a01.parentNode); // <p id="p01"></p>
  log(a01.parentElement); // <p id="p01"></p>

  log(a01.parentNode.id); // p01
  log(a01.parentElement.id); // p01

  log(div01.parentNode); // <body></body>
  log(div01.parentElement); // <body></body>

  log(document.body.parentNode); // <html></html>
  log(document.body.parentElement); // <html></html>

  log(document.body.parentNode.parentNode); // #document
  log(document.documentElement.parentNode); // #document
  log(document.documentElement.parentElement); // null
}

删除或替换子节点实例

<ul id="ul01">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
  <li>Item 4</li>
  <li>Item 5</li>
</ul>
/**
 * removeChild 删除特定子节点实例
 * replaceChild 替换特定子节点实例
 */

let refs = ul01.children;
console.log(refs); // HTMLCollection(5) [li, li, li, li, li]
console.log('');

ul01.removeChild(refs[2]);
ul01.removeChild(refs[2]);

console.log(refs); // HTMLCollection(3) [li, li, li]

let new_item = document.createElement('li');
new_item.innerHTML = 'Special X';
ul01.replaceChild(new_item, refs[1]);

获取滚动条的相关数据

<p id="message01" style="position: fixed;left: 20%;top:50%;color:RoyalBlue">(0, 0)</p>
<p id="message02" style="position: fixed;left: 60%;top:50%;color:Teal">(0, 0)</p>
<button type="button" id="scroll_button">Scroll to Paragraph</button>

<div id="content">
  <p id="p01">Paragraph 1</p>
  <p id="p02">Paragraph 2</p>
  <p id="p03">Paragraph 3</p>
  <p id="p04">Paragraph 4</p>
  <p id="p05">Paragraph 5</p>
</div>
body {
  height: 1000px;
  width: 2000px;
}

#content {
  width: 200px;
  height: 140px;
  padding: 10px;
  background-color: GreenYellow;
  overflow: scroll;
}

#content p {
  color: White;
  padding: 5px;
  width: 400px;
  height: 300px;
  border-radius: 5px;
}

#p01 {
  background-color: Orange;
}

#p02 {
  background-color: Yellow;
}

#p03 {
  background-color: RoyalBlue;
}

#p04 {
  background-color: Cyan;
}

#p05 {
  background-color: Purple;
}
/**
 * scrollLeft 返回特定元素实例的水平滚动条的当前滚动刻度
 * scrollTop 返回特定元素实例的垂直滚动条的当前滚动刻度
 * scrollWidth 返回特定元素实例中,其内容可被水平滚动的宽度
 * scrollHeight 返回特定元素实例中,其内容可被垂直滚动的高度
 * scrollIntoView 可使得特定元素实例,被显示在浏览器的当前窗口或特定窗格中
 */

scroll_button.onclick = function(event) {
  p03.scrollIntoView(); // p03 这个元素显示在当前窗口中
}

window.onscroll = function(event) {
  with(document.documentElement) {
    message01.innerHTML = `${scrollLeft}, ${scrollTop}`
  }
}

content.onscroll = function(event) {
  with(event.target) {
    message02.innerHTML = `${scrollLeft}, ${scrollTop}`
  }
}

console.log(document.body.scrollHeight); // 1000
console.log(document.body.scrollWidth); // 2000

- Book Lists -