首页
Search
1
解决visual studio code (vscode)安装时没有选择安装路径问题
138 阅读
2
Linux 下 Bash 脚本 bad interpreter 报错的解决方法
131 阅读
3
Arch Linux 下解决 KDE Plasma Discover 的 Unable to load applications 错误
107 阅读
4
如何在 Clash for Windows 上配置服务
77 阅读
5
Uniapp如何引入自定义样式文件
75 阅读
clash
服务器
javascript
全部
游戏资讯
登录
Search
加速器之家
累计撰写
1,061
篇文章
累计收到
0
条评论
首页
栏目
clash
服务器
javascript
全部
游戏资讯
页面
搜索到
624
篇与
的结果
2024-10-21
第11页
Front-end Engineer,前端开发工程师目前是一名前端开发工程师,主要负责前端规划、框架与架构、前端性能优化。专注前端技术,关注交互体验,擅长web ajax开发。坚信前端工程师的价值是最终能把技术和设计完美结合在一起。用最新的技术方案巧妙地帮助这些设计得以实现。
2024年10月21日
4 阅读
0 评论
0 点赞
2024-10-20
getScript在前端中请求js文件和jsonp
getScript在前端中使用的非常广泛,那么这里也分享下自己使用的ts版本的getScript:/** * 加载js文件 * @param {string} url 要加载的js文件链接 * @param {function} callback 回调函数 * @returns {Promise} 返回一个Promise对象,若加载失败或者超时,则reject */ const getScript = (url: string, callback: ()=>{}): Promise => { const head = document.getElementsByTagName('head')[0]; const script = document.createElement('script'); const timeout: number = 5000; // 过期时间 let timer: number; script.setAttribute('type', 'text/javascript'); script.setAttribute('charset', 'UTF-8'); script.setAttribute('src', url); if (sid) { script.setAttribute('id', sid); } const cleanup = () => { if (script.parentNode) { script.parentNode.removeChild(script); } if (timer) { clearTimeout(timer); } }; head.appendChild(script); return new Promise((resolve, reject) => { // 执行回调 const callbackFn = () => { if (timer) { clearTimeout(timer); } callback(); resolve(); }; script.onload = () => { callbackFn(); }; if (timeout) { timer = setTimeout(() => { cleanup(); reject(new Error(`get ${url} timeout`)); }, timeout); } }); }; 正常请求一个js文件,然后设置了一个5000ms的过期时间,若请求资源不成功,则进入到reject中。同时,getScript支持使用callback和Promise两种方式执行结果的回调,不过callback的方式无法获取到超时的情况:getScript('http://mat1.gtimg.com/libs/jquery2/2.2.0/jquery.min.js').then((jQuery: any)=>{ console.log(jQuery.fn.jquery); }).catch(e=>console.error('请求超时')); 这种方式,其实稍微改造一下,也是可以直接用来跨域,请求支持jsonp接口的。在url的后面添加上callback的请求参数,然后在回调里执行这个callback。 例如:const getScript = (url: string, data: {}): Promise => { const head = document.getElementsByTagName('head')[0]; const script = document.createElement('script'); const timeout: number = 5000; // 过期时间 let timer: number; let fecthCallBack: string = 'cb' + Date.now() + '_' + ('' + Math.random()).substr(-8); const cleanup = () => { if (script.parentNode) { script.parentNode.removeChild(script); } window[fecthCallBack] = () => {}; delete window[fecthCallBack]; if (timer) { clearTimeout(timer); } }; head.appendChild(script); // 将Object类型的数据转换为URL链接需要的参数 let paramObj = (params: any) => { let str = '', key, item; for (key in params) { if (typeof params[key] === 'object') { item = JSON.stringify(params[key]); } else { item = params[key]; } str += `&${key}=${encodeURIComponent(item)}`; } return str.substring(1); }; url += (~url.indexOf('?') ? '&' : '?') + paramObj(data) + '&callback=' + fecthCallBack; script.setAttribute('type', 'text/javascript'); script.setAttribute('charset', 'UTF-8'); script.setAttribute('src', url); return new Promise((resolve, reject) => { window[fecthCallBack] = (data: any) => { cleanup(); resolve(data); }; if (timeout) { timer = setTimeout(() => { cleanup(); reject(new Error('Timeout')); }, timeout); } }); };
2024年10月20日
9 阅读
0 评论
0 点赞
2024-10-20
js中parseInt与Math.floor的区别
网上有介绍parseInt与Math.floor区别的内容已经不少了,这里我还是想说下自己在使用过程中的区别 parseInt # 我们平时在使用parseInt时,主要是为了数据中的整数部分。但实际上,在官方的定义里,parseInt的第一个参数应当是string类型的。 parseInt(string, radix); 尤其是在ts中使用parseInt会更加明显,若直接传入一个数字类型的参数,则编辑器会提示此处应当传入一个字符串类型,这时就要求我们手动的转为字符串类型,比如使用num+''或者num.toString()。在不严格的情况下,js语言会自动进行隐式的类型转换。而且,使用parseInt获取整数部分时,是直接将小数部分扔掉:parseInt('12.3'); // 12 parseInt('6.9'); // 6 parseInt('4'); // 4 parseInt('-1.2'); // -1 parseInt('-1.9'); // -1 parseInt最大的一个功能是,可以将字符串类型的数字其他进制的数据转为十进制的数据。同时,parseInt也能让我们从数字和其他字母混合的字符串中提取出数字来,若以非数字类型开始的字符串,则无法转为数字,若以数字开头的字符串,则返回第一个非数字字符前所有的数字字符:parseInt('11', 8); // 9, 8进制中的11即为10进制中的9 parseInt('123.456'); // 123 parseInt('a123'); // NaN parseInt('123a456'); // 123 这种情况有一个使用的场景,比如有一个DOM元素上有style属性 我们在使用style获取高度时会带有单位,那么这里就可以用parseInt获取到纯数字(当然,我们还有其他方式来获取不带单位的数据,这里仅仅是举个例子):let height = document.querySelector('.wenzi').style.height; console.log( height ); // '200px' console.log( parseInt(height) ); // 200 Math.floor # Math.floor是专门用来操作数字的,该功能是获取小于等于参数的整数(向下取整),例如:Math.floor(12.3); // 12 Math.floor(6.9); // 6 Math.floor(4); // 4 Math.floor(-1.2); // -2 Math.floor(-1.9); // -2 可以看到,在获取整数部分这个功能,与parseInt对比发现,对于非负数来说效果是一样的,但是对于负数来讲,floor会向更小数字的方向寻找。若传入的参数不是数字类型的,返回的则是NaN。 建议在获取非负数的整数部分时,使用Math.floor 总结 # 若是操作纯数字型的数据,建议使用Math下的方法,若字符串类型的数字再使用parseInt,更加语义化一些。
2024年10月20日
3 阅读
0 评论
0 点赞
2024-10-20
博客里评论系统的前端总结
在之前的一篇文章里,曾经介绍过本博客的楼中楼评论系统的实现:如何实现一个楼中楼的评论系统,那时候主要是对后端系统和数据库设计的介绍,本篇文章主要是从前端的角度讲解评论系统的实现!评论系统最主要的两块是发表评论和评论列表,同时呢,发表评论成功后,刷新评论列表主要也是有两种方式: ajax的方式刷新,直接追加在特定的位置; 刷新整个页面,重新获取评论,然后定位到刚才发表的评论的位置; 本小蚊子博客的评论系统,是以ajax的方式获取评论列表,同时在发表评论成功后,也是以异步的方式更新评论列表。Vue组件的结构是:Comments.vue Publish.vue List.vue Unit.vue Publish.vue 1. 如何发表评论 # 用户对文章或者某个评论产生了共鸣,需要留言讨论一番,我们就需要用户能够把自己的评论也添加进去。评论的类型,细分的话,可以分为3类: 直接对文章发表评论,pid与replyid为空; 对一级评论进行回复,pid与replyid均为一级评论的id; 对楼中楼进行回复,pid为一级评论的id,replyid为你回复的评论的id 我这里前端的实现参考了oschina(开源中国)的评论方式。直接对文章评论,是直接在顶部的评论窗口进行输入;对其他评论进行回复时,采用弹窗的方式来进行回复。弹窗回复的好处就是,页面不用滚动,用户对某个评论的感知也能停留在这个位置;同时也不用增加各种不必要的小输入框来让用户。所有发表评论用到的组件都是同一个(Publish.vue),只不过表现的方式不一样而已。在发表评论成功后,通过事件通知机制$emit,更新数据结构list数组。当直接对文章评论时,使用splice操作list数组即可:this.list.splice(0, 0, item); // 在list数组的最前面添加评论内容 当进行楼中楼的评论时,其实是在item中的reply字段里,我们要先更新reply字段,然后再将item重新更新到list数组中:let item = this.list[index]; item.reply.push(replyItem); this.$set(this.list, index, item); // 或 // this.list.splice(index, 1, item); 在更新楼中楼的评论过程中,之前遇到了一个问题:当出现楼中楼的第一个评论时,数据更新但是页面没有更新,从第2个评论开始就能正常更新评论了!刚开始以为是Vue的字段更新后,导致调用的子组件里的数据不会更新。好一通排查后才发现原因竟然是:楼中楼是否显示使用item.num字段(当前评论里子评论的个数),上面的代码里只是更新了item.reply字段,但是没有更新item.num,导致第一个评论的自动更新老是有问题! 2. 登录的问题 # 之前博客的评论系统,接入的微博登录;一段运行时间后,运行得倒是也没有问题,不过接入微博登录有点大材小用了,最新的评论系统更新时,改为了用户输入昵称和邮箱后即可评论!用户发表评论后,即将用户的昵称和邮箱存储到cookie中,下次直接从cookie里后去即可! 3. 获取评论列表 # 在获取评论列表时,也是监听了页面的滚动事件,同时采用防抖和节流的策略,在用户将页面滚动到底部的时候再获取数据!在获取到数据后,即解绑滚动事件handleScroller() { const scroller = throttle(()=>{ const maxScrollTop = Math.max(document.body.scrollHeight, document.documentElement.scrollHeight) - window.innerHeight; const currentScrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop); if (maxScrollTop - currentScrollTop < 100 && !this.loaded) { this.loaded = true; this.getList(); // 获取数据 window.removeEventListener('scroll', scroller); } }, 300, 400); scroller(); window.addEventListener('scroll', scroller); } 4. 总结 # 评论系统是一项比较复杂的系统,我们这里也只是做了简单的工作而已,后续可能也会考虑,全部使用原生的js来实现!
2024年10月20日
4 阅读
0 评论
0 点赞
2024-10-20
js打乱数组的实战应用
在 js 中,能把数组随机打乱的方法有很多,每个方法都有自己的特点。 1. 打乱数组的方法 # 这里主要讲解 3 个打乱数组的方法。 1.1 随机从数组中取出数据 # 这个方法的详细操作步骤是:随机从数组中取出一个数组放入到新数组中,然后将该数据从原数组中删除,然后再随机取出下一个数,直到原数据的长度为 0。function randomArrByOut(arr) { let result = []; let arrTemp = arr.concat(); // splice会影响原数组,复制一个新的数组,防止影响原数组 while (arrTemp.length) { let index = Math.floor(Math.random() * arrTemp.length); result.push(arrTemp[index]); arrTemp.splice(index, 1); } return result; } const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]; randomArrByOut(arr); // [7, 1, 3, 8, 2, 4, 6, 5, 9] randomArrByOut(arr); // [8, 4, 3, 7, 9, 2, 1, 5, 6] 这个算法看似是O(n)的算法,但实际上arr.splice内部是一个O(n^2)的算法Array.prototype.splice 的内部实现:外部循环用来删除元素,内部的循环用来填充新添加的元素,或后面的元素向前移动,填充刚才被删除的元素的坑。总的算下来,这个算法的时间复杂度就是O(n^3)了。 1.2 sort 方法打乱 # 还有一种常见的方法就是使用数组自带的 sort 方法来打算数组,sort 方法是直接修改当前的数组:function randomSortBySort(arr) { arr.sort(() => Math.random() - 0.5); } 当前环节里所有的测试均在 Chrome 中。当我们使用 9 个数据,经过多次的测试发现,打乱的数据排布并不均匀:var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]; var n = 10000; var count = {}; while (n--) { randomSortBySort(arr); var index = arr.indexOf(1); count[index] ? count[index]++ : (count[index] = 1); } console.log(count); /* 数据1经过10000次打乱后的分布规律,主要集中在前2个 0: 2047 1: 1403 2: 947 3: 822 4: 777 5: 822 6: 992 7: 1008 8: 1182 */ 我们再把 arr 的数组扩展为 15,再进行测试:var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; var n = 10000; var count = {}; while (n--) { randomSortBySort(arr); var index = arr.indexOf(1); count[index] ? count[index]++ : (count[index] = 1); } console.log(count); // {0: 668, 1: 647, 2: 652, 3: 665, 4: 692, 5: 652, 6: 679, 7: 657, 8: 665, 9: 683, 10: 685, 11: 690, 12: 662, 13: 663, 14: 640} 可以发现每次打乱后的分布比较均匀,每个数字出现在每个位置的机会都是均等的!在V8 的源码中 L710 行中可以看到:function InnerArraySort(array, length, comparefn) { // In-place QuickSort algorithm. // For short (length
2024年10月20日
5 阅读
0 评论
0 点赞
1
...
31
32
33
...
125