阅读 1107
前端技术工具类文章

前端技术工具类文章

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。

前沿

vue.draggable

属性名称说明
group:group= "name",相同的组之间可以相互拖拽
sort:sort= "true",是否开启内部排序,如果设置为false,它所在组无法排序,在其他组可以拖动排序
delay:delay= "0", 鼠标按下后多久可以拖拽
touchStartThreshold鼠标移动多少px才能拖动元素
disabled:disabled= "true",是否启用拖拽组件
animation拖动时的动画效果,还是很酷的,数字类型。如设置animation=1000表示1秒过渡动画效果
handle:handle=".mover" 只有当鼠标移动到css为mover类的元素上才能拖动
filter:filter=".unmover" 设置了unmover样式的元素不允许拖动
draggable:draggable=".item" 那些元素是可以被拖动的
ghostClass:ghostClass="ghostClass" 设置拖动元素的占位符类名,你的自定义样式可能需要加!important才能生效,并把forceFallback属性设置成true
chosenClass:ghostClass="hostClass" 被选中目标的样式,你的自定义样式可能需要加!important才能生效,并把forceFallback属性设置成true
dragClass:dragClass="dragClass"拖动元素的样式,你的自定义样式可能需要加!important才能生效,并把forceFallback属性设置成true
dataIdAttrdataIdAttr: 'data-id'
forceFallback默认false,忽略HTML5的拖拽行为,因为h5里有个属性也是可以拖动,你要自定义ghostClass chosenClass dragClass样式时,建议forceFallback设置为true
fallbackClass默认false,克隆的DOM元素的类名
allbackOnBody默认false,克隆的元素添加到文档的body中
fallbackTolerance拖拽之前应该移动的px
scroll默认true,有滚动区域是否允许拖拽
scrollFn滚动回调函数
scrollSensitivity距离滚动区域多远时,滚动滚动条
scrollSpeed滚动速度

[countUp.js-数字滚动效果]

image.png

darkmode-js

Darkmode.js实现黑暗模式

Darkmode.js运用的是CSS里面的一个特性叫mix-blend-mode ,这个 属性描述了元素的内容应该与元素的直系父元素的内容和元素的背景如何混合,再加上Javascript的辅助判断哪些页面上的元素需要黑化的,哪些是不需要黑化的。

[使用wavesurfer.js绘制音频波形图]

wavesurfer.js是一个可自定义的语音音频可视化工具,建立于web audio和H5 canvas之上

将wavesurfer.js的包引用到项目中

<script src="https://unpkg.com/wavesurfer.js"></script>
复制代码

为wavesurfer.js开辟一个空间,用来画图

<``div id="waveform" class="waveform"></``div``>

在script标签中,创建一个wavesurfer实例,传递容器选择器及一些选项

var wavesurfer = WaveSurfer.create({
    container: '#waveform',
    waveColor: 'violet',
   cursorColor:'#ff0000',
   progressColor:'#0000ff',
});
复制代码

加载音频。用wavesurfer.js方法中的load(),直接传入音频路径即可,可以是在线音频

wavesurfer.load('audio.wav');
复制代码
    var playPause = document.querySelector('#playPause');
    playPause.addEventListener('click', function() {
        wavesurfer.playPause();
    });
    wavesurfer.on('play', function() {
        document.querySelector('#play').style.display = 'none';
        document.querySelector('#pause').style.display = '';
    });
    wavesurfer.on('pause', function() {
        document.querySelector('#play').style.display = '';
        document.querySelector('#pause').style.display = 'none';
    });
复制代码
btnStop.addEventListener('click', function () {
    wavesurfer.stop();
});
复制代码

demo中加入了时间插件(timeline),频谱插件(spectrogram)、光标插件(cursor)等

vue-pdf

1635397360(1).png

[js获取上、下级html元素 js删除html元素方法]

js获取下级html元素:htmlEle.childNode;

js获取上级html元素:htmlEle.parentNode;

js删除当前html元素: htmlEle.removeNode(true);  

js删除子级html元素:parEle.removeChild(childEle);

Object.values()

Object.values() 方法返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用[for...in]循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )。

[语法]

Object.values(obj)
复制代码

[参数]

  • obj

    被返回可枚举属性值的对象。

[返回值]

一个包含对象自身的所有可枚举属性值的数组。

[描述]

Object.values()返回一个数组,其元素是在对象上找到的可枚举属性值。属性的顺序与通过手动循环对象的属性值所给出的顺序相同。

[示例]

var obj = { foo: 'bar', baz: 42 };
console.log(Object.values(obj)); // ['bar', 42]

// array like object
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.values(obj)); // ['a', 'b', 'c']

// array like object with random key ordering
// when we use numeric keys, the value returned in a numerical order according to the keys
var an_obj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.values(an_obj)); // ['b', 'c', 'a']

// getFoo is property which isn't enumerable
var my_obj = Object.create({}, { getFoo: { value: function() { return this.foo; } } });
my_obj.foo = 'bar';
console.log(Object.values(my_obj)); // ['bar']

// non-object argument will be coerced to an object
console.log(Object.values('foo')); // ['f', 'o', 'o']
复制代码

Node.parentElement

返回当前节点的父元素节点,如果该元素没有父节点,或者父节点不是一个 DOM [元素],则返回 null

[语法]

parentElement = node.parentElement
复制代码

parentElement 是当前节点的父元素。它永远是一个 DOM [元素]对象,或者 null

[例子]

if (node.parentElement) {
    node.parentElement.style.color = "red";
}
复制代码

HTML DOM appendChild() 方法

appendChild() 方法可向节点的子节点列表的末尾添加新的子节点。

提示: 如果文档树中已经存在了 newchild,它将从文档树中删除,然后重新插入它的新位置。如果 newchild 是 DocumentFragment 节点,则不会直接插入它,而是把它的子节点按序插入当前节点的 childNodes[] 数组的末尾。

你可以使用 appendChild() 方法移除元素到另外一个元素。

<ul id="myList1"><li>Coffee</li><li>Tea</li></ul>
<ul id="myList2"><li>Water</li><li>Milk</li></ul>
<p id="demo">单击按钮将项目从一个列表移动到另一个列表中</p>
<button onclick="myFunction()">点我</button>
<script>
function myFunction(){
	var node=document.getElementById("myList2").lastChild;
	document.getElementById("myList1").appendChild(node);
}
</script>
复制代码
<script>
function changeLink(){
	document.getElementById('myAnchor').innerHTML="sss";
	document.getElementById('myAnchor').href="//www.sss.com";
	document.getElementById('myAnchor').target="_blank";
}
</script>
</head>
<body>
 
<a id="myAnchor" href="//www.xxxxx.com">xxxxx</a>
<input type="button" onclick="changeLink()" value="修改链接">
 
</body>
复制代码

[Vue事件总线:this.bus.bus.emit与this.bus.bus.on]

1.创建Vue实例

复制//main.js
Vue.prototype.$bus = new Vue();
复制代码

2.发射事件

复制//GoodsList
this.$bus.$emit("aaa")
复制代码

3.监听事件

复制//home.vue
this.$bus.$on("aaa",()=>{
   this.$refs.scroll.scroll.refresh()
})
复制代码

拼接元素的字符串,利用父元素的innerHTML设置父元素的内容

image.png

创建 DOM 元素以及相应的追加方式

appendChild 是将一个元素追加到另一个元素的最后, 不会覆盖父元素原有的内容。

image.png

JavaScript Array slice() 方法

slice() 方法可从已有的数组中返回选定的元素。

slice()方法可提取字符串的某个部分,并以新的字符串返回被提取的部分。

注意:  slice() 方法不会改变原始数组。

JavaScript Array filter() 方法

filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。

注意:  filter() 不会对空数组进行检测。

注意:  filter() 不会改变原始数组。

JavaScript entries() 方法

entries() 方法返回一个数组的迭代对象,该对象包含数组的键值对 (key/value)。

迭代对象中数组的索引值作为 key, 数组元素作为 value。

github.com/PanJiaChen/…

  1. keep-alive 本质是把应该销毁的组件缓存起来,当再次需要的时候去读取缓存的组件信息而不是重新渲染,所以 keep-alive 必须包裹一个组件才能生效。
  2. 使用了 include and exclude 会按照这个规则进行匹配缓存那些页面,不使用会缓存所有。
  3. 如果使用了第二条的筛选规则,那么必须配置对照和 name,不然无法正确缓存。

文档原句:
匹配首先检查组件自身的 name 选项,如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值)。匿名组件不能被匹配

  1. keep-alive 内部的 router-view ,填写 key 的时候,需要谨慎 ,不然会出现问题。

比如在编辑信息的时候,用户打开了两个标签页使用了同一个组件,不使用 key 就会复用这同一个组件 但是我们需要的是渲染两个,使用不同的 key 就会分别渲染两个,而有时候 key 又会生成多余的页面。

  1. 取消缓存页面只需要把 include and exclude 中不需要缓存的 name 删除即可,因为源代码中会监听这个两个字段,删除缓存的组件。
  mounted () {
    this.$watch('include', val => {
      pruneCache(this, name => matches(val, name))
    })
    this.$watch('exclude', val => {
      pruneCache(this, name => !matches(val, name))
    })
  }
复制代码

vuex案例-配置指定界面缓存

VUEX:

export default const views = {
 state: {
    visitedViews: [], // 已经点击访问过的View, 用于展示为tag-tabs
    cachedViews: [] // 哪些Views需要使用keep-alive进行缓存,默认不加noCache的都会缓存(根据业务需求)
  },
  mutations: {
    // 增加浏览记录路由对象
    ADD_VISITED_VIEW (state, { route, token }) {
      if (state.visitedViews.some(v => v.path === route.path)) return
      state.visitedViews.push(route)
      if (route.name && route.meta && !route.meta.noCache) {
        state.cachedViews.push(route.name)
      }
    }
  },
  actions: {
    addVisitedViews ({ commit }, { route, token }) {
      commit('ADD_VISITED_VIEW', { route, token })
    }
  },
  getter: {
   // 页面
    cachedViews: state => state.views.cachedViews,
    visitedViews: state => state.views.visitedViews
  }
}
复制代码

创建路由:

// router
import Layout from '@/components/layout'
const _import_ = file => () => import('@/views/' + file + '.vue')
export const aysncRoutesMap = [
 {
    path: '/homepage',
    component: Layout,
    meta: { title: 'Homepage', icon: 'iconfont icon-yunzhuomian', role: ['admin', 'user'] },
    children: [
      {
        path: 'home',
        name: 'Homepage',
        component: _import_('Homepage/index'),
        meta: { title: 'Home', icon: 'nocturne icon-home', isHome: true, isCache:true}
      }
    ]
  },
  {
    path: '/dashboard',
    component: Layout,
    meta: { title: 'dashboard', role: ['admin', 'user'] },
    children: [
      {
        path: 'dash',
        name: 'Dashboard',
        component: _import_('Dashboard/index'),
        meta: { title: 'Dashboard', icon: 'nocturne icon-dash', isHome: false, isCache:false }
      }
    ]
  }
]
复制代码

JavaScript Array concat() 方法

concat() 方法用于连接两个或多个数组。

concat() 方法不会更改现有数组,而是返回一个新数组,其中包含已连接数组的值。

JavaScript splice() 方法

splice() 方法用于添加或删除数组中的元素。

规定应该删除多少元素。必须是数字,但可以是 "0"。
如果未规定此参数,则删除从 index 开始到原数组结尾的所有元素

注意: 这种方法会改变原始数组。

返回值

如果仅删除一个元素,则返回一个元素的数组。 如果未删除任何元素,则返回空数组。

JavaScript Array some() 方法

some() 方法用于检测数组中的元素是否满足指定条件(函数提供)。

some() 方法会依次执行数组的每个元素:

  • 如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。
  • 如果没有满足条件的元素,则返回false。

注意:  some() 不会对空数组进行检测。

注意:  some() 不会改变原始数组。

typescript 中的keyof、 in

keyof与Object.keys略有相似,只是 keyof 是取 interface 的键而且 keyof 取到键后会保存为联合类型。

image.png

in用于取联合类型的值。主要用于数组和对象的构造。

image.png

HTML DOM createElement() 方法

实例

创建指定文本的按钮:

var btn=document.createElement("BUTTON");\
var t=document.createTextNode("CLICK ME");\
btn.appendChild(t);
复制代码

new Map()

JavaScript的对象(Object),本质上是键值对的集合(Hash结构),但是传统上只能用字符串当作键。这给它的使用带来了很大的限制。
为了解决这个问题,ES6提供了Map数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。

image.png

Array.prototype.forEach()

forEach()  方法对数组的每个元素执行一次给定的函数。

Mutation

更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type)  和 一个 回调函数 (handler) 。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数

Action 类似于 mutation,不同在于:

  • Action 提交的是 mutation,而不是直接变更状态。
  • Action 可以包含任意异步操作。

Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。

forEach() 的 continue 与 break

forEach() 本身是不支持的 continue 与 break 语句的

使用 return 语句实现 continue 关键字的效果:

continue 实现

实例

var arr = [1, 2, 3, 4, 5];\
\
arr.forEach(function (item) {\
    if (item === 3) {\
        return;\
    }\
    console.log(item);\
});\
复制代码

[MouseEvent]

当鼠标进行某种操作时,就会生成一个event对象,该对象记录着鼠标触发事件时的所有属性。

altkey : 触发鼠标事件时是否alt 按键被按下,如果按下,则返回true,否则返回 fasle。

button:  事件属性返回一个阿拉伯数字 , 0代表 按下 左键 ,1 代表按下 滚轮 ,2 代表按下 右键。

offsetX、offsetY :事件属性返回触发事件时 鼠标相对于事件源元素 的X,Y坐标,标准事件没有对应的属性。

clientX、clientY : 事件属性返回当事件被触发时鼠标指针相对于浏览器页面(或客户区)的水平坐标、垂直坐标。

pageX、pageY:事件属性返回当事件被触发时鼠标指针相对于整个页面左上角的水平坐标、垂直坐标。

screenX、screenY:事件属性返回当事件被触发时鼠标位置相对于用户屏幕水水平坐标、垂直坐标,此时的参照点也就是原点是屏幕的左上角。

image.png

call()、apply()、bind()

例 1

obj.objAge;  // 17
obj.myFun()  // 小张年龄 undefined
复制代码

例 2

shows()  // 盲僧 
复制代码

比较一下这两者 this 的差别,第一个打印里面的 this 指向 obj,第二个全局声明的 shows() 函数 this 是 window ;

1,call()、apply()、bind() 都是用来重定义 this 这个对象的!

如:

obj.myFun.call(db);    // 德玛年龄 99
obj.myFun.apply(db);    // 德玛年龄 99
obj.myFun.bind(db)();   // 德玛年龄 99
复制代码

以上出了 bind 方法后面多了个 () 外 ,结果返回都一致!

由此得出结论,bind 返回的是一个新的函数,你必须调用它才会被执行。

2,对比call 、bind 、 apply 传参情况下

 

obj.myFun.call(db,'成都','上海');     // 德玛 年龄 99  来自 成都去往上海
obj.myFun.apply(db,['成都','上海']);      // 德玛 年龄 99  来自 成都去往上海  
obj.myFun.bind(db,'成都','上海')();       // 德玛 年龄 99  来自 成都去往上海
obj.myFun.bind(db,['成都','上海'])();   // 德玛 年龄 99  来自 成都, 上海去往 undefined
复制代码

  

微妙的差距!

从上面四个结果不难看出:

call 、bind 、 apply 这三个函数的第一个参数都是 this 的指向对象,第二个参数差别就来了:

call 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔,直接放到后面 obj.myFun.call(db,'成都', ... ,'string' )。

apply 的所有参数都必须放在一个数组里面传进去 obj.myFun.apply(db,['成都', ..., 'string' ])。

bind 除了返回是函数以外,它 的参数和 call 一样。

当然,三者的参数不限定是 string 类型,允许是各种类型,包括函数 、 object 等等!

正则表达式

\将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。例如,“n”匹配字符“n”。“\n”匹配一个换行符。串行“\”匹配“``”而“(”则匹配“(”。
^匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。
$匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。
*匹配前面的子表达式零次或多次。例如,zo*能匹配“z”以及“zoo”。*等价于{0,}。
+匹配前面的子表达式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。
?匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“does”或“does”中的“do”。?等价于{0,1}。
{n}n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。
{n,}n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。
{n,m}m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。
?当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+”将匹配所有“o”。
.匹配除“n`”之外的任何单个字符。要匹配包括“n”在内的任何字符,请使用像“(.
x|y匹配x或y。例如,“z|food”能匹配“z”或“food”。“(z|f)ood”则匹配“zood”或“food”。
[xyz]字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。
[^xyz]负值字符集合。匹配未包含的任意字符。例如,“[^abc]”可以匹配“plain”中的“p”。
[a-z]字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。
[^a-z]负值字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。
\b匹配一个单词边界,也就是指单词和空格间的位置。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。
\B匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。
\d匹配一个数字字符。等价于[0-9]。
\D匹配一个非数字字符。等价于[^0-9]。
\f匹配一个换页符。等价于\x0c和\cL。
\n匹配一个换行符。等价于\x0a和\cJ。
\r匹配一个回车符。等价于\x0d和\cM。
\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。
\S匹配任何非空白字符。等价于[^ \f\n\r\t\v]。
\t匹配一个制表符。等价于\x09和\cI。
\v匹配一个垂直制表符。等价于\x0b和\cK。
\w匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9_]”。
\W匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。

❤️关注+点赞+收藏+评论+转发❤️,原创不易,鼓励笔者创作更好的文章

点赞、收藏和评论

我是Jeskson,感谢各位人才的:点赞、收藏和评论,我们下期见!(如本文内容有地方讲解有误,欢迎指出☞谢谢,一起学习了)

我们下期见!

github收录,欢迎Star1024bibi.com

「欢迎在评论区讨论,掘金官方将在掘力星计划活动结束后,在评论区抽送100份掘金周边,抽奖详情见活动文章」

文章分类
前端