将css转化为react-native stylesheet
webpack-loader:react-native-css-loader
cli tool:css-to-react-native-stylesheet
rules transformer:css-to-react-native
css text transformer:css-to-react-native-transform
批量自动化删除新浪微博代码
因为一些黑历史而带来了烦恼,年轻的时候不懂事,以为留下的足迹是好的,如今去看却满目苍夷,鄙夷那时幼稚的自己。好不容易通过邮箱找回了密码,但是发现自己竟然几年之间发了 4000 多条微博。总不可能一条一条删吧,网上搜了一下,发现了一个自动删除的脚本。但是这个脚本在删除时,会将当前页全部删除,这回导致微博自动刷新页面,脚本也就不能继续执行了。于是做了改进,得到如下代码:
const sleep = (time) => new Promise(resolve => setTimeout(resolve, time)) const script = document.createElement('script') script.setAttribute('src', 'https://lib.sinaapp.com/js/jquery/2.0.3/jquery-2.0.3.min.js') script.onload = function() { var latestTime = Date.now() async function scrollToBottom() { $('html, body').scrollTop($(document).height()) await sleep(800) // 等下一页加载完 // 往下拉,拉到底部 if ($('[node-type="lazyload"]').length && !$('a.page.prev').length) { scrollToBottom() return } console.log('加载完毕。') $('html, body').scrollTop(0) console.log('开始删除。') deleteWeibo() } async function deleteWeibo() { if ($('a[action-type="feed_list_delete"]').length > 1) { const $date = $('.WB_detail:first a[date]') const time = +$date.attr('date') // 设定一个时间,当删除程序发现要删除的微博发布时间大于这个时间时,删除程序直接停止 const date = +new Date('2016-01-01 00:00:00') if (time > date) { console.log('到达了设定的时间,停止删除。') clearInterval(timer) return } $('a[action-type="feed_list_delete"]')[0].click() await sleep(500) // 等删除确认窗口打开 $('a[action-type="ok"]').each(function() { this.click() }) await sleep(500) // 等待删除请求完毕 latestTime = Date.now() // 记录最后一次删除操作时间 deleteWeibo() } else { // 处理最后一条 var mid = $('div[mid]').last().attr('mid') // 进入下一页之后,上一页的最后一条没有被删掉,用 ajax 将它删除 const deleteLastOne = () => $.post('https://weibo.com/aj/mblog/del', { mid: mid }).fail(async () => { console.log('删除最后一条失败,正在尝试重新删除。') await sleep(1000) deleteLastOne() }) deleteLastOne() console.log('进入上一页。') $('a.page.prev')[0].click() await sleep(1000) // 确保下一页已经加载 scrollToBottom() } } scrollToBottom() // // 心跳检测,是否还在正常跑,如果没有跑了,就重启服务 const heartbeat = 30000 var timer = setInterval(() => { const currentTime = Date.now() if (currentTime - latestTime < heartbeat * 1.5) { return } console.log('检测到任务失败,正在尝试重新启动。') $('[action-type="feed_list_page_morelist"] ul li:first a')[0].click() // 通过点击全部按钮来恢复加载微博 $('html, body').scrollTop(0) }, heartbeat) } document.head.appendChild(script)
使用方法:
- 将上方红色字修改为你想要停止的日前,如果要删除全部微博,删除上面灰色部分
- 进入个人中心页面 https://weibo.com/{weiboid}/profile
- 通过下拉,拉到最底部,出现导航,选择页面,跳转到最后一页
- 打开开发者工具执行上面的代码。
这段代码的逻辑是,通过模拟滚动下拉和鼠标点击事件,逐条删除微博(删除太快会出现 416 报错,应该是微博后台的一个防 DDos 策略)。但是删除完一页之后,我们不能按照正常的逻辑,删除下一页,因为如果我们这个时候点击下一页,那么就会实际进入下下一页,而不是下一页,中间有一页会被漏掉。了解接口设计的同学应该很清楚,翻页的时候,当前页是按 limit 的规则输出的,所以在对待这个场景时,我选择通过模拟点击“上一页”的办法来解决。这也是为什么要求你在运行这段脚本的时候跳转到最后一页才开始执行。面对前文提到的,会自动刷新的问题,解决办法是,在留下最后一条的时候,不删,而是直接点击“上一页”,这样,页面不会自动刷新,而会把上一页的内容加载进来。但是留下的这条怎么办?自己发一个 ajax 请求去删除即可。
吐槽一下,写多了 ES6+ 的语法,再写 function 声明代码感觉不适应。
互联网的一个特点是开放,但是,比较恐怖的一点时,我们没有一个“删除键”。我们个人的信息,一旦上网,就永远留在了网络空间,无论你想不想。这有的时候是好事,可以起到备份作用,但有的时候是坏事。我想,如果我以后做一款应用,一定要提供“备份”“一键全删”的功能。
在 leveldb 的使用过程中,发现一个比较忧伤的问题,level 这个包是依赖 levelup 去起一个 leveldb 的,一旦一个实例生成,就会在数据库目录下生成一个 LOCK 文件,这种情况下,你不可以再用另外一个 levelup 去起一个实例。解决的办法是,创建一个函数,用以在多个程序之间共享由 levelup 起来的实例。而且由于 js 是单线程的,所以,只要是在同一个进程中(某些异步情况下要格外小心),就可以避免被锁问题。
-
自己都不知道怎么来的你博客,大概把你所有的杂目录下随便翻了翻觉得up很有意思
然后往简介里面翻了一下发现还是天健园的学长~
向学长学习~#784 潘小安 2019-05-30 18:00 -
相互交流~#785 回复给#784 否子戈 2019-06-01 12:30
-
~#793 回复给#785 潘小安 2019-06-04 14:00
在页面闲时执行任务
在页面空闲的时候,执行一些计算或某些特殊的后台任务,这样可以避免对用户操作带来卡顿的问题。虽然js支持异步编程,但是即使某些任务是异步执行的,但是因为js是单线程程序,所以,如果一个任务需要花费比较长的时间去进行计算,那么即使它是在异步回调的时候执行,也会带来界面卡顿,而如果用户在这个卡顿期间进行交互操作,就会明显感到卡死状态,体验不好。
有没有一种办法避免这种情况发生?当然有,最好的方式是使用webworker,启用另外一个线程去执行这个需要消耗大量时间的运算。因为webworker和用户界面所在的线程相互不影响,所以,不会给用户带来卡顿感。当计算完毕之后,通过postMessage实现数据传递,对于用户而言,几乎无感。
但是在一些特殊情况下,我们需要在用户界面所在的主线程去执行这种程序。比如,我们要在这个任务中获取DOM的一些信息。这个时候,我们要想办法让这个任务不对用户的操作造成影响。
web标准提供了requestIdleCallback这个接口,它的用法有点像requestAnimationFrame,它主要用于在浏览器闲时执行某个任务。比如:
var a = 0 requestIdleCallback(() => { a ++ })
上面这段代码,给浏览器下了一个命令,当浏览器空闲的时候,执行a ++。
不过requestIdleCallback会有一些兼容性问题,我们只能通过一些手段来使它在低版本浏览器可以用:
export const requestIdleCallback = window.requestIdleCallback || function(cb, delay = 1000) { const start = Date.now() const action = () => cb({ didTimeout: false, timeRemaining: function() { return Math.max(0, 50 - (Date.now() - start)) }, }) const id = setTimeout(() => { timeout.id = setTimeout(action, delay) timeout.reset = () => { clearTimeout(timeout.id) timeout.id = setTimeout(action, delay) } document.addEventListener('keydown', timeout.reset, true) document.addEventListener('mousedown', timeout.reset, true) document.addEventListener('touchstart', timeout.reset, true) document.addEventListener('touchmove', timeout.reset, true) document.addEventListener('mousemove', timeout.reset, true) window.addEventListener('scroll', timeout.reset, true) window.addEventListener('resize', timeout.reset, true) }) var timeout = { id, reset: null } return timeout } export const cancelIdelCallback = window.cancelIdelCallback || function(timeout) { if (!timeout) { return } clearTimeout(timeout.id) document.removeEventListener('keydown', timeout.reset) document.removeEventListener('mousedown', timeout.reset) document.removeEventListener('touchstart', timeout.reset) document.removeEventListener('touchmove', timeout.reset) document.removeEventListener('mousemove', timeout.reset) window.removeEventListener('scroll', timeout.reset) window.removeEventListener('resize', timeout.reset) timeout.reset = null timeout.id = null }
cancelIdelCallback用于取消前面下达的命令,参数是requestIdleCallback的返回值。
不过有一个问题,就是requestIdleCallback是只执行一次的,如果我们想要做一个守护程序,在浏览器空闲的时候,就开始运行这个守护程序,应该怎么做呢?
/** * 创建一个在空闲时执行的任务 * @param {*} fn */ export function autoidle(fn, interval = 1000, immediate = true) { var idle const run = () => { const action = () => { idle = requestIdleCallback(run, interval) } asyncx(fn)().then(action).catch(action) } const start = () => { cancelIdelCallback(idle) idle = requestIdleCallback(run, interval) } const stop = () => { cancelIdelCallback(idle) } if (immediate) { start() } return { start, stop } }
这个函数可以创建一个守护程序,它可以在你的浏览器空闲的时候不断运行,但你的浏览器开始忙碌的时候,又不会运行的效果。另外,它返回两个函数,start 和 stop,用以在必要的时候停止和重启任务。
-
技术人员的文章看不懂。
监控用户在当前页面的停留时间
我们希望知道一个用户在当前这个页面停留的时间,这中间要考虑到用户通过切换浏览器tab的情况,把所有用户动作都记录下来。
const tracers = [] // 进入 tracers.push({ type: 'enter', time: Date.now(), }) // 切屏 const visibilitychangeFn = () => { if (document.visibilityState === 'hidden') { tracers.push({ type: 'focusout', time: Date.now(), url: window.location.href, requestId: this.getRequestId(), }) } else { tracers.push({ type: 'focusin', time: Date.now(), }) } } document.addEventListener('visibilitychange', visibilitychangeFn) // 离开 const unloadFn = () => { tracers.push({ type: 'leave', time: Date.now(), url: window.location.href, requestId: this.getRequestId(), }) record({ type: 'usertracer', tracers, stay: tracers[tracers.length - 1].time - tracers[0].time, }) } window.addEventListener('beforeunload', unloadFn)
function record(info) {}
通过一个traces数组,记录了用户从进入这个页面,在这个页面停留、切换tab,到最后离开这个页面的时间。
-
现实是你用的几个api好像有兼容问题~#780 JC 2019-05-24 14:57
-
我博客大部分文章,都是不考虑兼容性的,实现一个东西,不可能面面俱到,最重要的是为读者提供可供参考的思路#781 回复给#780 否子戈 2019-05-28 18:17
-
这个怎么说呢,
大部分开发肯定都是要考虑兼容性的,
就算是参考,
也是片面的,
唉,
不说了#782 回复给#781 JC 2019-05-28 18:18
Unsplash
可免费商用的图片素材供应商。
https://unsplash.com/
思源宋体
思源宋体、思源黑体这两款字体都是开源免费(可商用)的高质量字体,由adobe发布,值得收藏。
https://source.typekit.com/source-han-serif/cn/
手机端真机调试
https://segmentfault.com/a/1190000018613578