元素通用属性-2

Element

我们常用的属性和方法大都是来自 Element 类型的

id

id 属性可以获取/设置 该元素的id属性,

比如

<p id="source">文本1</p>


<script>
  let source = document.getElementById("source");
  source.id = 'newid'
</script>   

children 只读

children 属性可以获取该元素的所有子元素,

看这个例子

<p id="source">p文本1
  <!-- 注释1 -->
  <span id='text1'>span文本1</span>
  p文本
  2
  <span id='text2'>span文本2</span>
  p文本
  3
</p>


<script>
  let source = document.getElementById("source");
  console.log(source.children)
</script>   

通过运行结果可以发现,

children属性返回的是对象是 HTMLCollection 类型,

这个类型 功能类似 数组,里面存放的是 html元素对象,

可以使用 for of 遍历, 也可以使用索引获取其中的元素

比如

for (let child of source.children)
  console.log(child.id)

source.children[1]

前面讲的 Node 类型的 childNodes 属性返回的是所有的子节点,包括 html元素、文本、注释

innerHTML、outerHTML

innerHTML 可以用来获取一个元素对象 内部 HTML文本

outerHTML 可以用来获取一个元素对象 全部 HTML文本

比如

<div id='div1' class="type1 type2">
 
      <div id='text'>
        内部文本
      </div> 
  
</div>

<script>
  const ele = document.getElementById("div1");

  console.log('innerHTML是', ele.innerHTML)
  console.log('outerHTML是', ele.outerHTML)
</script>

运行结果如下

innerHTML是 
 
    <div id="text">
      内部文本
    </div> 


outerHTML是 <div id="div1" class="type1 type2">
 
    <div id="text">
      内部文本
    </div> 

</div>

除了获取HTML文本,也可以设置HTML文本 比如

<div id='div1' class="type1 type2">
  外部文本
  <div id='text'>
    内部文本
  </div> 
  
</div>

然后,在console中依次执行下面的语句,看看html文档和界面的变化

const ele = document.getElementById("div1");
ele.innerHTML= `<div id='text'>
      新的内部文本
    </div> `
ele.outerHTML= `<div id='div1' class="newtype1 newtype2">
    新的外部文本
    <div id='text'>
      新的内部文本2
    </div>  
</div>`

获取内部元素

前面我们学习过全html文档范围获取元素, 使用下面的方法

document.getElementsByClassName()
document.getElementsByTagName()
document.querySelector()
document.querySelectorAll()

如果我们只要在某个元素的内部获取元素,通用的针对某个元素调用这些方法即可

let ele = document.querySelector('#main')

ele.getElementsByClassName()
ele.getElementsByTagName()
ele.querySelector()
ele.querySelectorAll()

同样,如果没有找到符合条件的元素,querySelector 返回 null

获取上级元素

closest() 方法获取符合条件的 最接近 的上级元素

参数是一个css选择表达式

比如:

<div id='div1' class="type1 type2">
  <div id='div2' class="type1 type2">
    <div id='div3' class="type3">
      <div id='text'>
        内部文本
      </div> 
    </div> 
  </div> 
</div>

<script>
const inner = document.getElementById("text");

console.log('得到元素的id是', inner.closest('.type2').id)
</script>

运行结果显示: 得到元素的id是 div2

因为 #div2 比 #div1 更靠近 #text 元素


如果自身也匹配,则返回本元素自身,因为自身更接近自身 😊

比如,把上面的最后一行换为

<div id='div1' class="type1 type2">
  <div id='div2' class="type1 type2">
    <div id='div3' class="type3">
      <div id='text' class="type2">
        内部文本
      </div> 
    </div> 
  </div> 
</div>

<script>
const inner = document.getElementById("text");

console.log('得到元素的id是', inner.closest('.type2').id)
</script>

运行结果是 得到元素的id是 text


如果没有匹配的元素,则返回null

比如,把上面的最后一行换为

console.log('得到元素为', inner.closest('.nnnn'))

运行结果是 得到元素为,null

添加元素

Element方法中,有好几个用来添加节点。

after() / before() / append()

after 是给当前元素节点,添加一些 后续弟弟节点

参数可以是1个或者 多个节点对象

参数可以是 元素对象 (添加后成为html元素) 或者 字符串(添加后成为文本节点)

比如

<body>
  <p id='target'>原来的元素</p>
</body>

<script>
  let p = document.getElementById('target')

  const new1 = document.createElement("p");
  new1.textContent = '新元素1';
  const new2 = document.createElement("p");
  new2.textContent = '新元素2';

  p.after(new1,new2,'abc');
</script>



相反,before 是给当前元素节点,添加一些 前置哥哥节点

参数可以是1个或者 多个节点对象

参数可以是 元素对象 (添加后成为html元素) 或者 字符串(添加后成为文本节点)

比如

<body>
  <p id='target'>原来的元素</p>
</body>

<script>
  let p = document.getElementById('target')

  const new1 = document.createElement("p");
  new1.textContent = '新元素1';
  const new2 = document.createElement("p");
  new2.textContent = '新元素2';

  p.before(new1,new2,'abc');

</script>



append 是给当前元素节点,添加一些 子节点

参数可以是 1个或者 多个节点对象

参数可以是 元素对象 (添加后成为html元素) 或者 字符串(添加后成为文本节点)

比如

<body>
  <p id='target'>原来的元素</p>
</body>

<script>
  let p = document.getElementById('target')


  const new1 = document.createElement("p");
  new1.textContent = '新元素1';
  const new2 = document.createElement("p");
  new2.textContent = '新元素2';

  p.append(new1,new2,'abc');

</script>

insertAdjacentHTML()

使用 after() / before() / append(),必须先使用 document.createElement() 创建一个元素对象

然后再调用新对象的方法,创建内容。

写起来比较麻烦。

可以使用 insertAdjacentHTML 方法直接写元素对应的html文本内容。

比如


<p>薪资统计</p>

<script>
  let pEle = `
      <br><br>
      <p>小张: <mark>15000</mark></p>
      <p>小李: <mark>18000</mark></p>
`
  document.querySelector('p')
  .insertAdjacentHTML("beforeend", pEle)
</script>

insertAdjacentHTML 方法就是在DOM 对象的 某个位置 插入新的html节点。

  • 第2个参数 就是要插入的节点对应的HTML文本

  • 第1个参数 指定插入节点的位置

    • afterbegin

      插入内容 作为 当前节点的 第一个子节点

    • beforeend

      插入内容 作为 当前节点的 最后一个子节点

    • beforebegin

      插入内容 作为 当前节点的 前一个哥哥节点

    • afterend

      插入内容 作为 当前节点的 下一个弟弟节点

删除元素

remove() 方法用来删除元素自身,比如

<body>
  <p id='target1'>原来的元素1</p>
  <p id='target2'>原来的元素2</p>
</body>

<script>
  let p = document.getElementById('target1') 
  p.remove();
</script>

还可以这样删除

document.getElementById('target1').outerHTML="";

支持这种方式的浏览器更广泛,包括IE

替换元素

可以使用 outerHTMLinnerHTML 属性替换元素


<body>
  <p id='target1'>原来的元素1</p>
  <p id='target2'>原来的元素2</p>
</body>

<script>
  document.getElementById('target1').outerHTML=`
    <p id='target11'>新的元素1</p>
  `

  document.getElementById('target2').innerHTML=`
    <span>新的元素21</span>
    <span>新的元素22</span>
  `
</script>


也可以使用 replaceWith 方法替换元素,比如

<p id='p1'>原来的内容</p>


<script>
  let p = document.getElementById('p1')
  const span = document.createElement("span");
  span.textContent = '新内容';

  p.replaceWith(span);
</script>

获取元素属性

getAttribute() 可以用来获取元素的属性, getAttribute() 返回值都是字符串的形式

如下:

<a id="hey" 
  style='color:green'  
  href="/" 
  class='nav nav-item'
  attr1='自定义属性'>
  一个链接
</a>

<script>
let a = document.getElementById('hey')

console.log(a.getAttribute('id'))
console.log(a.getAttribute('style'))
console.log(a.getAttribute('href'))
console.log(a.getAttribute('class'))
console.log(a.getAttribute('attr1'))
</script>

运行结果如下

hey
color:green
/
nav nav-item
自定义属性

有的属性,也可以直接通过 元素对象.属性 的方式获取元素的属性

比如

a.id

但是这种方式只能获取元素的标准属性, 不能获取自定义非标准属性的值

比如

a.attr1 // 得到的值是 undefined

而且有的属性获取的结果和 getAttribute() 不一样,返回值不一定是字符串

比如

a.style // 得到的值 类似 Object类型
a.href  // 得到的值是全路径

设置元素属性

setAttribute() 可以用来设置元素的属性

<a id="hey" style='color:green'  href="/" attr1='自定义属性'>一个链接</a>

<script>
let a = document.getElementById('hey')

a.setAttribute('id', 'new-hey')
a.setAttribute('style' , 'color:blue')
a.setAttribute('href', 'https://www.byhy.net')
a.setAttribute('attr1', '自定义属性2')

</script>

setAttribute() 参数 都是字符串的形式


也可以直接通过 元素对象.属性 的方式设置元素的属性

比如

a.id = 'new-hey3'

但是这种方式只能设置元素标准属性, 不能获取自定义非标准属性的值

而且有的设置方式和 setAttribute()不一样,因为 元素对象.属性 的方式值不都是字符串

比如

a.style.color = 'green'

style 属性其实不是 Element 类型里面的,是 HtmlElement 类型里面的

删除元素属性

removeAttribute() 用来删除元素的属性

比如

a.removeAttribute('id')
a.removeAttribute('style')
a.removeAttribute('href')
a.removeAttribute('attr1')

class属性

class属性操作, 除了前面讲的通用方法,还可以这样操作

className

className 可以用来获取和设置元素的class属性

之所以不直接用 class 作为属性名,是为了避免和 js 的关键字 class 冲突

比如

<div id='div1' class="type1 type2">
   元素内容
</div>

<script>
  const ele = document.getElementById("div1");

  console.log('class 原来是', ele.className)
  ele.className = 'new-type'
  console.log('class 现在是', ele.className)
</script>

在浏览器中运行结果是

class 原来是 type1 type2
class 现在是 new-type

上面的示例可以看出 className 是对元素 class属性整体 当作一个字符串操作的。

classList

如果想单独操作某个class ,不改变其它class属性,推荐使用 classList 属性

classList 属性对应一个 DOMTokenList 类型, 有一些方便操作属性值的方法,

其中比较常用的是

  • contains 方法

返回true和false表示是否包含指定元素

  • remove 方法

删除某个属性,其它属性不动

  • add 方法

添加某个属性


看下面的代码示例,通过 添加删除属性,灵活地控制元素的显示效果(隐藏还是显示)


<head>
  <style>
    .hide {
      display:none
    }
  </style>
</head>
<body>

<button>隐藏/显示</button>

<div id='div1' class="type1">
   元素内容
</div>

<script>
  
  // 注册事件回调函数
  document.querySelector('button').addEventListener(
    "click", 
    function (){
      const ele = document.getElementById("div1"); 

      if (ele.classList.contains('hide')){
        ele.classList.remove("hide");
      }
      else{
        ele.classList.add("hide");
      }
    }
  );

</script>
</body>

HtmlElement

HtmlElement 有如下常用属性方法

innerText、outerText

HtmlElement 的 innerText 和 Node 的 textContent 属性都可以 获取/设置 元素内部的文本内容

区别是:

innerText 展示的是该元素对应的可以呈现在界面上的文本内容

textContent 展示的是元素内部所有的文本内容,包括不可见的部分

看一个例子

<p id="source">
<span id=text>看一下<br>这个内容<br>如何变化</span>
<span style="display:none">隐藏内容</span>
</p>

<script>
const source = document.getElementById("source");

console.log('innerText', source.innerText)
console.log('textContent', source.textContent)
</script>

运行结果如下

innerText 看一下
这个内容
如何变化
textContent 
看一下这个内容如何变化
隐藏内容

innerText 还可以用来 设置 节点的内部文本内容

在console运行

source.innerText = '新内容'

结果可以发现 p节点内容变成了

<p id="source">新内容</p>

outerText 用来 获取 元素文本,结果和 innerText 一样

但是 设置 元素的文本内容,就是把整个元素变成一个文本节点,

在console运行

source.outerText = '新内容2'

你会发现连p节点本身都消失了,变成了一个文本 新内容2

style

style属性的值是 CSSStyleDeclaration 类型, 类似 Object类型, 可以通过这个对象的属性来 获取、设置 元素的样式

比如

<a id="link" style='color:green;text-decoration:underline'  href="/" >一个链接</a>

在控制台执行

let a = document.getElementById('link')

a.style.color
a.style['text-decoration']

a.style.color = 'red'
a.style['text-decoration'] = 'none'

focus()

focus方法可以让该元素获取输入焦点,前提是这种元素可以获取输入焦点

比如


<input type="text" id="text-box" size="20" value="白月黑羽">

<br><br>

<button>聚焦在输入框</button>

<script>
  let b1 = document.querySelector('button')

  b1.addEventListener('click', ()=> {
    let input = document.querySelector('#text-box')
    input.focus()
  })
</script>

click()

click 方法 模拟鼠标点击该元素

比如


<button>按钮1</button>
<button>按钮2</button>

<script>
  let [b1,b2] = document.querySelectorAll('button')

  b1.addEventListener('click', ()=> {
    alert('按钮1被点击了')
  })
  
  b2.addEventListener('click', ()=> {
    alert('即将模拟点击按钮1')
    b1.click()
  })
</script>