# DOM

# dom 操作

# 操作节点

  1. 创建节点
var a = createElement("p"); //创建元素节点
var a = createDocumentFragment(); // 创建文档片段,这一部分不会占用空间也就是虚拟节点
var a = createTextNode("元素内容"); //创建文本节点
  1. 添加,移除,替换,查询
var div = document.getElementById("div1")
var p = createElement("p")

div.appendChild(p) //增加

div.removeChild(p) // 移除

var new = createElement("div")
div.replaceChild(new,p) // 替换

const div1 = document.getElementById('div1')
// 获取标签集合
const divList = document.getElementsByTagName('div')
const containerList = document.getElementByClassName('.className')

const p =document.querySelector('p')// 获取一个p标签的dom
const pList = document.querySelectorAll('p')// 选择器获取集合

# 操作样式

  • 操作样式: property形式
const div1 = doucment.getElementById("div1");
div1.style.width = "100px";
console.log(div1.style.width); // 100px
console.log(div1.className); // 样式名
console.log(div1.nodeName); //标签名
  • 操作样式: attribute形式,但是会修改标签结构
div1.setAttribute("data-name", "imooc");
div1.getAttribute("data-name");
div1.setAttribute("style", "width:height:30px");

# 窗口属性、滚动条、元素

# 滚动条

  1. 求滚动条距离顶部或者屏幕最左侧的距离
var x = window.pageXOffset //横向距离
var y = window.pageYOffset //纵向
以上方法不兼容 ie8和ie8以下浏览器 所以需要使用以下方法

var x = document.body.scrollLeft
var y = document.body.scrollTop
var x = document.documentElement.scrollLeft
var y = document.documentElement.scrollTop
以上方法兼容性比较混乱,但是两种方法不可能同时有值,所以通常会写成以下方法(相加)获取滚动距离

var x = document.body.scrollLeft + document.documentElement.scrollLeft
var y = document.body.scrollTop + document.documentElement.scrollTop

通常会封装一个方法获取滚动条的距离

function getScrollToOrLeft() {
  if (window.pagetXOffset) {
    return {
      x: window.pageXOffset,
      y: window.pageYOffset
    };
  } else {
    return {
      x: document.body.scrollLeft + document.documentElement.scrollLeft,
      y: document.body.scrollTop + document.documentElement.scrollTop
    };
  }
}
  1. 让滚动条滚动
  • window.scroll(x,y) x,y 是坐标
  • window.scrollTo(x,y)
  • window.scrollBy(x,y): 这里是累加滚动,在原有基础上累加

实现阅读器自动阅读的功能,包含开始和暂停

var start = document.getElementByClassName("start")[0]; // 开始自动阅读的dom
var stop = document.getElementByClassName("stop")[0]; // 暂停阅读
let timer;
let lock = true;
// 加锁式的编程思想
start.onclick = function() {
  if (lock) {
    timer = setInterval(() => {
      window.scrollBy(0, 10);
    }, 100);
    lock = false;
  }
};

// 暂停
end.onclick = function() {
  clearInterval(timer);
  lock = true;
};

其实这种加锁式的编程思想很常见,比如说给加载长列表做性能优化,不让他每一次都去请求接口

data:return {
  isEnd: false,
  lock:false
}

async getMoreData(){
  if(isEnd){
    return
  }
  if(lock){
    return
  }
  this.lock = true
  const res = await getAPI()
  this.lock = false
  if(res.code === 200){
    if(res.data.limit < conifg.limit){
      // 最后一页了
      this.isEnd = true
    }
    if(res.data.length === 0){
      this.list = res.data
    }else{
      this.list = [...(this.list,res.data)]
    }
  }
}
  1. 求文档的总高度和总宽度
var x = document.body.scrollWidth
var y = document.body.scrollHeight
var x = document.documentElement.scrollWidth
var y = document.documentElement.scrollHeight
以上方法兼容性比较混乱,但是两种方法不可能同时有值,所以通常会写成以下方法(相加)获取滚动距离

var x = document.body.scrollWidth + document.documentElement.scrollWidth
var y = document.body.scrollHeight + document.documentElement.scrollHeight
  1. 判断当前屏幕是否触底

滚动条距顶部的高度 + 可视区域高度 = 文档总高度 则代表已经触底

// 滚动条距顶部的高度
var scrollTop = () => {
  if (window.pageYOffset) {
    return window.pageYOffset;
  } else {
    return document.body.scrollTop + document.documentElement.scrollTop;
  }
};
// 可视区域高度
var viewHeight = () => {
  if (window.innerHeight) {
    return window.innerHeight;
  } else {
    if (document.compatMode === "CSS1Compat") {
      return document.documentElement.clientHeight;
    } else {
      return document.body.clientHeight;
    }
  }
};
// 文档总高度
var documentHeight = () => {
  return document.body.scrollHeight + document.documentElement.scrollHeight;
};

window.onScroll = () => {
  if ((scrollTop + viewHeight = documentHeight)) {
    console.log("触底了");
  }
};
  1. 有效的滚动方法

    /**
     * search === scrollTop方法
     * @description  平滑滚动到指定区域
     * @param { node=> dom ,position=> 指定的位置}
     * node节点具备以下属性
     * overflow-y: scroll; // 设置node节点为滚动区域
     * height: 100vh;
     * -webkit-overflow-scrolling : touch; // 开启ios滚动硬件加速,否则很卡会被认为是bug
     */
    export function scrollSmoothTo(node: any, position: any, fn = function () {}) {
      if (!window.requestAnimationFrame) {
        window.requestAnimationFrame = function (callback) {
          return setTimeout(callback, 17)
        }
      }
      // scrollTo的兼容处理
      if (!node.scrollTo) {
        node.scrollTo = function (left: any, top: any) {
          node.scrollLeft = left
          node.scrollTop = top
        }
      }
      let scrollTop = node.scrollTop
      // 当前滚动高度
      // 滚动step方法
      const step = () => {
        // 距离目标滚动距离
        const distance = position - scrollTop
        // 目标滚动位置
        scrollTop = scrollTop + distance / 5
        if (Math.abs(distance) < 1) {
          node.scrollTo(0, position)
          fn()
        } else {
          node.scrollTo(0, scrollTop)
          node.requestAnimationFrameObj = requestAnimationFrame(step)
        }
      }
      step()
    }
    
    

# 可视区窗口尺寸

可视区窗口指的是 html 生效部分,不包含导航栏工具栏,控制台

var x = widnow.innerWidth
var y = window.innerHeight
IE8IE8以下浏览器不兼容

var x = document.documentElement.clientWidth
var y = document.documentElement.clientHeight
标准模式,任何浏览器兼容

var x = document.body.clientWidth
var y = document.body.clientHeight
适用于怪异模式

封装兼容的方法

function getViewPortOffset() {
  if (window.innerWidth) {
    return {
      x: window.innerWidth,
      y: window.innerHeight
    };
  } else {
    if (document.compatMode === "CSS1Compat") {
      return {
        x: document.documentELement.clientWidth,
        y: document.documentElement.clientHeight
      };
    } else {
      return {
        x: document.body.clientWidth,
        y: document.body.clientHeight
      };
    }
  }
}

# 元素

求元素的尺寸

  1. 调用 dom 的 getBoundingClientRect(),返回这个元素的坐标和宽高,但是是静态结果

top,left,bottom,right 代表元素以左上角为基础的分别代表的距离,也就是坐标,另外还返回了 width 和 height,但是在 ie 浏览器是没有这俩属性的

  1. offsetWidth/offsetHeight,求元素的可视尺寸
var div = document.getElementById("div1");
var x = div.offsetWidth; // 求的是视觉上的宽高,因为都是标准盒模型,但是这里不会包含margin
var y = div.offsetHeight;

求元素的位置

  • offsetLeft
  • offsetTop
<div style="position:relative;top:100px;left:100px;width:300px;height:300px">
  <div class="demo" style="width:100px;height:100px;background:red;position:absolute;top:100px;left:100px"></div>
</div>
var div = document.getElementByClassName("demo")[0];
var offsetLeft = div.offsetLeft; //100 求得是这个元素和最近的有定位的父级的距离

# 全屏和非全屏

  const toggleFullScreen = () => {
      if (state.isFullScreen) {
        document.exitFullscreen().catch((e) => {
          console.log(e)
        })
      } else {
        document.documentElement.requestFullscreen().catch((e) => {
          console.log(e)
        })
      }
    }

    // 监听尺寸变化
    window.onresize = () => {
      const fullDom = document.fullscreenElement
      state.isFullScreen = !!fullDom
      emit('toggle-fullscreen')
    }
Last update: 3/6/2022, 9:03:36 AM