一、正则捕获

JS 正则捕获:把符合某个规则的字符串获取到;

  • 常见的捕获方法:
  1. RegExp.prototype.exec(str);
  2. String.prototype.match();

懒惰性

  1. let reg = /\d+/;
  2. let str = 'hello111 hello222 hello333';
  3. console.log(reg.exec(str)); // ['111', index.....]
  4. console.log(reg.exec(str)); // ['111', index.....]
  5. console.log(reg.exec(str)); // ['111', index.....]
  6. console.log(reg.lastIndex); // 0
  7. console.log(str.match(reg)); // ['1111']
  8. console.log(str.match(reg)); // ['1111']
  9. console.log(str.match(reg)); // ['1111']

取消懒惰性:给正则增加修饰g

  1. let reg2 = /\d+/g;
  2. let str2 = 'hello111 hello222 hello333';
  3. console.log(reg2.exec(str2));
  4. console.log(reg2.exec(str2));
  5. console.log(reg2.exec(str2));
  6. console.log(reg2.lastIndex);
  7. console.log(str2.match(str2));

贪婪性:按照匹配做多的去捕获,

解决贪婪性:给量词元字符后面加 ?

分组捕获:

  1. let reg3 = /hello(\d+)/g; // 使用小括号表示正则分组
  2. console.log(reg3.exec(str)[1]);
  3. console.log(reg3.exec(str)[1]);
  4. console.log(reg3.exec(str)[1]);
  • 除了通过[索引]访问分组,在 RegExp 上有几个属性记录正则分组捕获的内容
  • RegExp.$1 表示第 1 个分组的捕获内容; 在 RegExp 上有 $1-$9 表示第 1 到第 9 个分组内容
  • RegExp[‘$&’] 表示整个正则捕获到的内容
  1. console.log(RegExp.$1);
  2. console.log(RegExp['$&']);

二、正则的高级应用

1. 配合replace使用

String.prototype.replace(匹配内容, ‘替换内容’);

  1. let str = 'zhufeng2018 zhufeng2019';
  • 把字符串中的 zhufeng 替换成 珠峰
  1. let result = str.replace('zhufeng', '珠峰');
  2. console.log(result); // 珠峰2018 zhufeng2019
  • 一次只能替换一个,那么有没有什么办法一次都替换掉呢?
  1. replace(正则, callback); // replace配合正则使用时
  1. let i = 0;
  2. let reg = /(zhufeng)/g;
  3. let r2 = str.replace(reg, function (...arg) {
  4. // 回调函数的参数:
  5. // 第一个:整个正则匹配到的内容
  6. // 如果有分组,会从第二个参数
  7. // 倒数第二个参数是 本次捕获的的起始索引位置
  8. // 最后一个参数是当前原始字符串
  9. i++;
  10. console.log(arg);
  11. return '珠峰'
  12. });
  13. console.log(r2);
  14. console.log(i); // 2 说明回调函数执行了 2 次;

2. 格式化时间字符串: 按照时间模板格式时间字符串

  • “2019/6/30 17:50:23” => ‘06-30 17:50’
  • 2.1 获取时间字符串中所有时间数字
  1. let str2 = "2019/6/30 17:50:23";
  2. let reg2 = /\d+/g;
  3. let ary = str2.match(reg2);
  4. console.log(ary);
  • 2.2 判断如果这些数字比 10 小,需要补 0
  1. let addZero = ary.map(item => +item < 10 ? '0' + item : item);
  2. console.log(addZero);
  • 2.3 根据模板把时间格式化
  1. let tmp = '{0}年{1}月{2}日 {3}时{4}分{5}秒';
  2. let tmpReg = /\{(\d)\}/g;
  3. let result2 = tmp.replace(tmpReg, function ([, index]) {
  4. return ary[index];
  5. });
  6. console.log(result2);
  • 扩展到原型上
  1. String.prototype.myFormatTime = function (tmp = '{0}年{1}月{2}日 {3}时{4}分{5}秒') {
  2. let ary = this.match(/\d+/g).map(item => +item < 10 ? '0' + item : item);
  3. return tmp.replace(/\{(\d)\}/g, (...[, index]) => ary[index]);
  4. };
  5. console.log("2018/4/30 17:50:23".myFormatTime('{1}-{2} {3}:{4}:{5}'));

3. url查询参数格式化

  1. let url = 'http://www.zhufeng.cn?name=mabin&age=18&form=zf&addre=hebei';
  • 把上面的url参数的转换成一个对象:{name: ‘mabin’, age: ‘18’}
  1. let params = {};
  2. let reg3 = /([^?=&]+)=([^?=&]+)/g;
  3. url.replace(reg3, (str, key, value) => params[key] = value);
  4. console.log(params);
  • 扩展到原型上
  1. String.prototype.urlSeries = function () {
  2. let params = {};
  3. let reg3 = /([^?=&]+)=([^?=&]+)/g;
  4. this.replace(reg3, (str, key, value) => params[key] = value);
  5. return params
  6. };
  7. let result3 = url.urlSeries();
  8. console.log(result3);

4. 获取数据类型

  1. Object.isTypeOf = function (val) {
  2. let res = Object.prototype.toString.call(val); // "[object Xxxx]"
  3. let reg = /^\[object ([a-zA-Z]+)\]$/; // 在正则使用某些特殊元字符的原义时需要转义
  4. let exec = reg.exec(res)[1];
  5. return exec.toLowerCase();
  6. };
  7. console.log(Object.isTypeOf(1));

三、JS 盒子模型属性

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. <style>
  7. * {
  8. margin: 0;
  9. padding: 0;
  10. }
  11. .box {
  12. /* css盒子模型属性: context (内容宽高) + padding + border + margin */
  13. /* w3c盒模型:内容宽高是不包含 padding 和 border 的 */
  14. /* IE盒模型:宽度包含 padding 和 border */
  15. width: 300px;
  16. height: 1220px;
  17. background-color: red;
  18. padding: 50px;
  19. border: 20px solid blue;
  20. margin: 50px auto;
  21. overflow-y: scroll;
  22. }
  23. </style>
  24. </head>
  25. <body>
  26. <div class="box" id="box">
  27. 【联播+】4月8日,习近平等中央领导同志参加了首都义务植树活动。习近平挥锹铲土,扶苗培土,与广大少先队员和市民们一起劳动。植树现场一片热火朝天景象。
  28. “我们的根扎在劳动人民之中。”习近平曾这样发自肺腑地说道。
  29. 1969年初,不满16岁的习近平来到陕北农村插队,一头扎进最基层。在农村生活的7年间,他什么活儿都干过,乡亲们说他是“吃苦耐劳好后生”。
  30. 从政之后,习近平不改劳动本色,从贫困山村到基层社区,他走进群众中间,一起种树、打糍粑、炸酥肉……所到之处,都留下了他与人民一同劳动的温暖记忆。
  31. 央视网用八张海报,带你重温过去,感受习近平总书记与人民同劳动的暖心瞬间。
  32. 【联播+】4月8日,习近平等中央领导同志参加了首都义务植树活动。习近平挥锹铲土,扶苗培土,与广大少先队员和市民们一起劳动。植树现场一片热火朝天景象。
  33. “我们的根扎在劳动人民之中。”习近平曾这样发自肺腑地说道。
  34. 1969年初,不满16岁的习近平来到陕北农村插队,一头扎进最基层。在农村生活的7年间,他什么活儿都干过,乡亲们说他是“吃苦耐劳好后生”。
  35. 从政之后,习近平不改劳动本色,从贫困山村到基层社区,他走进群众中间,一起种树、打糍粑、炸酥肉……所到之处,都留下了他与人民一同劳动的温暖记忆。
  36. 央视网用八张海报,带你重温过去,感受习近平总书记与人民同劳动的暖心瞬间。
  37. </div>
  38. <script src="js/4-js盒子模型属性.js"></script>
  39. </body>
  40. </html>

JS盒模型:通过JS中的属性和方法获取元素的属性信息

  1. let box = document.getElementById('box');

client

  1. clientWidth / clientHeight
    clientWidth 内容宽度 + 左右padding
    clientHeight 内容高度 + 上下padding
  1. console.log(box.clientWidth);
  2. console.log(box.clientHeight);
  1. clientLeft / clientTop
    clientLeft 左边框
    clientTop 上边框
  1. console.log(box.clientLeft);
  2. console.log(box.clientTop);
  1. offsetWidth / offsetHeight
    offsetWidth = clientWidth(内容宽+左右padding) + 左右边框
    offsetHeight = clientHeight(内容高+上下padding) + 上下边框
  1. console.log(box.offsetWidth);
  2. console.log(box.offsetHeight);
  1. scroll系列
    scrollLeft(横向滚动条卷去的距离) / scrollTop(纵向滚动条卷去的距离)
    滚动条 卷去的距离,默认是0,具体是多少要看滚动条滚动了多少
  • 获取浏览器的窗口滚动的距离
  1. let sc = document.documentElement.scrollTop || document.body.scrollTop;
  2. console.log(sc);
  1. scrollHeight/scrollWidth
  2. 没有溢出时:scrollHeight/scrollWidth 等于 clientHeight/clientWidth
  3. 内容溢出时:scrollHeight = clientHeight + 溢出内容高度;
  4. 内容溢出时:scrollWidth= clientWidth + 溢出内容高度;
  • 获取浏览器的窗口的盒模型属性:
  1. let winW = document.documentElement.clientWidth || document.body.clientWidth;
  2. let winH = document.documentElement.clientHeight || document.body.clientHeight;
  3. function win(attr, val) {
  4. if (typeof val !== "undefined") {
  5. document.documentElement[attr] = document.body[attr] = val;
  6. }
  7. return document.documentElement[attr] || document.body[attr];
  8. }
  9. console.log(win('scrollTop'));
  10. console.log(win('screenTop', 1000));

四、offsetLeft和offsetTop 偏移值

  • offsetLeft / offsetTop
  1. let outer = document.getElementById('outer');
  2. let inner = document.getElementById('inner');
  3. let center = document.getElementById('center');
  4. console.log(inner.offsetParent); // div#outer
  5. console.log(center.offsetLeft);
  • 父级参照物:距离当前元素最近的有定位属性的父级元素,如果没有的话默认 body;
  • 一般我们需要的是某个元素距离body的offsetLeft,所以就需要一级一级的向上查找
  1. function offset(ele) {
  2. let left = ele.offsetLeft;
  3. let top = ele.offsetTop;
  4. let parent = ele.offsetParent;
  5. // 只要找到的父级参照物存在且该参照物不是 body 就一直向上查找(一直找到 body 为止)
  6. while (parent && parent.nodeName.toLowerCase() !== 'body') {
  7. left += parent.offsetLeft + parent.clientLeft;
  8. top += parent.offsetTop + parent.clientTop;
  9. parent = parent.offsetParent;
  10. }
  11. return {
  12. left,
  13. top
  14. }
  15. }
  16. console.log(offset(center));