zoukankan      html  css  js  c++  java
  • 原生js操作DOM基础-笔记

    原文参考http://mp.weixin.qq.com/s?__biz=MzU3MDA0NTMzMA==&mid=2247485490&idx=1&sn=15197b4b53e0669e4a017e54a31fb39c&source=41#wechat_redirect

    使用原生js为了提高效率,纯js操作dom
    一 查询DOM
    document.querySelector()参数是任意css选择器格式,只会返回第一个匹配到值
    document.querySelectorAll()同上,返回结果不同,会返回所有查找到的值

    尽量在父元素中查找指定dom,减少document的整个文档查找,这样可以简化选择器并提高性能。

    与getElementsByTagName()这些方法的比较,querySelector()的结果不是动态的,当我们动态添加元素时,集合不会更新
    代码:
    const elements1 = document.querySelectorAll('div')
    const elements2 = document.getElementsByTagName('div')
    const newElement = document.createElement('div')
    document.body.appendChild(newElement)
    elements1.length === elements2.length // 0 1 结果false

    querySelectorAll()返回的结果不用调用node方法,结果也不是一个数组(是伪数组),需要转为数组才能使用数组的方法
    const myElements=document.querySelectorAll('.cla')
    Array.from(myElements).forEach(doSomeThing)
    Array.prototype.forEach.call(myElements,doSomeThing)
    [].forEach.call(myElements,doSomeThing)

    每个元素都有一些引用‘家族’的不需要说明的只读属性(即element属性),并且是动态的,基于元素的
    myElements.children子节点
    myElements.firstElementChild第一个子节点
    myElements.lastElementChild最后一个子节点
    myElements.previousElementSibling前一个子节点
    myElements.nextElementSibling后一个子节点
    node属性,除了parentElement可以是任何类型节点
    myElements.childNodes
    myElements.firstChild
    myElements.lastChild
    myElements.previousSibling
    myElements.nextSibling
    myElements.parentNode
    myElements.parentElement

    通过nodeType来判断节点的类型

    检查节点的原型链可以使用instanceof

    二 修改类和属性
    修改类
    myElement.classList.add()
    myElement.classList.remove()
    myElement.classList.toggle()
    访问属性
    myElement.value
    myElement.value = 'test'// 赋值
    设置多属性
    Object.assign(myElement,{
    value:'test',
    id:'app'
    })
    以下方法会导致浏览器重绘消耗性能
    getAttribute()
    setAttribute()
    removeAttribute()

    三添加css样式
    使用驼峰形式
    myElement.style.marginLeft = '1px'// 只会获取明确属性
    window.getComputedStyle(myElement)// 可以获取次元素所有css属性集合,包括继承下来的
    window.getComputedStyle(myElement).getPropertyValue('width')// 获取全部集合中的一种(如宽度)


    四修改DOM
    element1.appendChild(element2)
    element1.insertBefore(element2,element3)// 在容器element1中,将element2插入到element3之前

    五克隆一个元素
    let myEleClone = myElement.cloneNode()// 参数为true将创建一个深层副本,它的子元素也会被克隆

    六创建
    创建元素
    document.createElement('div')
    创建文本节点
    document.createTextNode('hell')

    七删除
    parentBox.removeChild(myElement)// 从父容器中删除子元素
    myElement.parentNode.removeChild(myElement)

    八读写元素属性
    innerHTML='<p>test</p>'// 元素中添加html内容
    textContent='test'// 只能添加纯文本

    九事件监听
    使用addEventListener方法可以不断绑定事件,事件都会触发
    myElement.addEventListener('click',function(event){
    console.log(event.target);
    })
    event.target是触发事件的元素

    阻止默认事件e.preventDefault()
    阻止事件冒泡e.stopPropagation()

    myElement.addEventListener('click',function(){},true)
    第一个参数是事件类型,第二个参数是回调函数,第三个参数是布尔值,true表示事件在捕获阶段执行false事件在冒泡阶段执行。默认是false

    removeEventListener()删除事件监听器
    myElement.addEventListener('click',function(e){})// 第一个参数是事件类型,第二个参数是回调函数

    事件委托
    列表的每个列表需要添加绑定事件,可以使用这种方式,在父元素上绑定事件,利用冒泡原理在判断触发事件的元素,节约性能
    parentBox.addEventListener('click',function(e){
    console.log(e.target);
    })

    十 动画
    使用window.requestAnimationFrame()来同步更新,将更改安排到浏览器下次重绘中。
    格式
    const start = window.performance.now()
    const duration = 2000
    window.requestAnimationFrame(function fadeIn(now){
    consot progress = now - start
    myElement.style.opacity = progress / duration
    if(progress < duration){
    window.requestAnimationFrame(fadeIn)// 递归
    }
    })

    十一 封装自己方法
    const $ = function $(selector, context = document) {
    const elements = Array.from(context.querySelectorAll(selector))
    return {
    elements,
    html(newHtml){
    this.elements.forEach(element => {
    element.innerHTML = newHtml
    })
    },
    css (newCss) {
    this.elements.forEach(element => {
    Object.assign(element.style, newCss)
    })
    return this
    },
    on (event, handler, options){
    this.elements.forEach(element => {
    element.addEventListener(event, handler, options)
    })
    return this
    }
    }
    }

  • 相关阅读:
    洛谷 P1567 统计天数【最长上升子序列/断则归一】
    洛谷 P3742 umi的函数【构造】
    洛谷 P1036 选数【背包型DFS/选or不选】
    nyoj zb的生日【背包型DFS/选or不选】
    POJ 3628 Bookshelf 2【背包型DFS/选or不选】
    【AHOI2013复仇】从一道题来看DFS及其优化的一般步骤和数组分层问题【转】
    洛谷 P1217 [USACO1.5]回文质数 Prime Palindromes【取回文数/数论/字符串】
    洛谷 P1004 方格取数 【多线程DP/四维DP/】
    Codeforces Round #449 (Div. 2) B. Chtholly's request【偶数位回文数】
    Codeforces Round #449 (Div. 2) A. Scarborough Fair【多次区间修改字符串】
  • 原文地址:https://www.cnblogs.com/victory820/p/6885639.html
Copyright © 2011-2022 走看看