012019.6

批量自动化删除新浪微博代码

因为一些黑历史而带来了烦恼,年轻的时候不懂事,以为留下的足迹是好的,如今去看却满目苍夷,鄙夷那时幼稚的自己。好不容易通过邮箱找回了密码,但是发现自己竟然几年之间发了 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)

使用方法:

  1. 将上方红色字修改为你想要停止的日前,如果要删除全部微博,删除上面灰色部分
  2. 进入个人中心页面 https://weibo.com/{weiboid}/profile
  3. 通过下拉,拉到最底部,出现导航,选择页面,跳转到最后一页
  4. 打开开发者工具执行上面的代码。

这段代码的逻辑是,通过模拟滚动下拉和鼠标点击事件,逐条删除微博(删除太快会出现 416 报错,应该是微博后台的一个防 DDos 策略)。但是删除完一页之后,我们不能按照正常的逻辑,删除下一页,因为如果我们这个时候点击下一页,那么就会实际进入下下一页,而不是下一页,中间有一页会被漏掉。了解接口设计的同学应该很清楚,翻页的时候,当前页是按 limit 的规则输出的,所以在对待这个场景时,我选择通过模拟点击“上一页”的办法来解决。这也是为什么要求你在运行这段脚本的时候跳转到最后一页才开始执行。面对前文提到的,会自动刷新的问题,解决办法是,在留下最后一条的时候,不删,而是直接点击“上一页”,这样,页面不会自动刷新,而会把上一页的内容加载进来。但是留下的这条怎么办?自己发一个 ajax 请求去删除即可。

吐槽一下,写多了 ES6+ 的语法,再写 function 声明代码感觉不适应。

互联网的一个特点是开放,但是,比较恐怖的一点时,我们没有一个“删除键”。我们个人的信息,一旦上网,就永远留在了网络空间,无论你想不想。这有的时候是好事,可以起到备份作用,但有的时候是坏事。我想,如果我以后做一款应用,一定要提供“备份”“一键全删”的功能。

12:37:52 已有0条回复
302019.5

在 leveldb 的使用过程中,发现一个比较忧伤的问题,level 这个包是依赖 levelup 去起一个 leveldb 的,一旦一个实例生成,就会在数据库目录下生成一个 LOCK 文件,这种情况下,你不可以再用另外一个 levelup 去起一个实例。解决的办法是,创建一个函数,用以在多个程序之间共享由 levelup 起来的实例。而且由于 js 是单线程的,所以,只要是在同一个进程中(某些异步情况下要格外小心),就可以避免被锁问题。

17:41:07 已有3条回复
  1. 自己都不知道怎么来的你博客,大概把你所有的杂目录下随便翻了翻觉得up很有意思
    然后往简介里面翻了一下发现还是天健园的学长~
    向学长学习~
    #784 潘小安 2019-05-30 18:00 回复
  2. 相互交流~
    #785 回复给#784 否子戈 2019-06-01 12:30 回复
  3. ~
    #793 回复给#785 潘小安 2019-06-04 14:00 回复
082019.5

在页面闲时执行任务

在页面空闲的时候,执行一些计算或某些特殊的后台任务,这样可以避免对用户操作带来卡顿的问题。虽然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,用以在必要的时候停止和重启任务。

17:09:58 已有1条回复
  1. 技术人员的文章看不懂。
    #779 repostone 2019-05-13 17:33 回复
072019.5

监控用户在当前页面的停留时间

我们希望知道一个用户在当前这个页面停留的时间,这中间要考虑到用户通过切换浏览器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,到最后离开这个页面的时间。

10:19:56 已有3条回复
  1. 现实是你用的几个api好像有兼容问题~
    #780 JC 2019-05-24 14:57 回复
  2. 我博客大部分文章,都是不考虑兼容性的,实现一个东西,不可能面面俱到,最重要的是为读者提供可供参考的思路
    #781 回复给#780 否子戈 2019-05-28 18:17 回复
  3. 这个怎么说呢,
    大部分开发肯定都是要考虑兼容性的,
    就算是参考,
    也是片面的,
    唉,
    不说了
    #782 回复给#781 JC 2019-05-28 18:18 回复
212019.4

2019免费版权(可商用)的web设计素材资源指北

2091 年 4 月 18 日,对视觉中国的处罚决定出炉,天津市网信办对网站运营主体汉华易美(天津)图像技术有限公司作出从重罚款的处罚。当天盘后,视觉中国(000681)发布公告称行政处罚金额为:30 万元

商业版权是商业公司赚钱的重要途径,一方面通过维权收取版权费,另一方面保护自己的设计成果。但是对于 web 设计者、开发者而言,版权是挡住创意的重要一步。对于创意的作者,在快速实现自己的想法时,如何绕过版权,快速实现创意呢?比较理想的是选择比较合理的开源产品来使用,通过遵守开源协议来使用该产品,以此绕过版权问题。但是,对于 web 设计素材而言,则没有那么容易,特别是对于 web 开发者而言,即使网上找到一些满意的素材,也不敢随意在自己的产品中使用。那么,究竟应该如何选择和寻找适合我们需要的 web 设计素材呢?

常见版权形式

有很多种版权协议形式,但是,对于使用者而言,一定要认真阅读素材供应商提供的版权文件。国外的大部分素材网站都会提供 pdf 的 license 文档,如果你的项目中使用了它们的素材,应该下载这个 pdf 文件,放在你的代码库旁边一起管理。常见的版权方式有:

  • 未经授权不允许使用
  • 个人免费使用,商业未经授权不允许使用
  • 有限使用(attribute),通常需要你在你的产品显著位置注明素材来源及作者
  • 素材版权购买,一般素材平台拥有销售版权的权利,素材作者将作品托管在平台,由平台统一售卖
  • 按等级打包收费,例如素材作者方将素材打包为不同的包,每个包包含的素材数量不同,钱越多数量越多
  • 终身授权与包时授权,通常由素材作者自己建立网站进行销售,目前较多是按年和按月授权
  • 会员制,会员无限授权,通过注册会员,按周期缴会员费,会员可无限使用素材,会员过期不续费将失去该权利
  • 免费版权使用,可商用
  • 开源免费,遵守开源协议

从上面的这些版权方式你可以发现,其实网上很多声称“免费下载”的素材是存在坑的,因为“免费下载”并不代表你可以“免费使用”,下载的目的可能是学习和演示,而非使用在你的产品中,因此,免费下载一定与使用没有任何关系,而且通常是供应商设下的陷阱。在下载时,读者一定要阅读清楚素材的版权文件,而不能直接将下载的素材使用在自己的产品中。

最理想的使用方式是完全免费(可商用)的版权协议,没有任何限制,随意使用。但是这样会存在一个问题,就是使用者在免费获得素材之后,又为素材附加了自己的使用协议,向后面的使用者收费。因此,比较合理的是基于使用协议的免费可商用版权,即限定使用者必须遵循的条件,从而避免上述情况发生,而这种协议在开源领域最为广泛,因此,越来越多的编辑性素材创作者开始考虑开源自己的作品,例如下面会提到的思源家族字体

图片

图片的版权是最为复杂的。主要针对两类图片:摄影作品,绘制作品。故名思议,摄影作品是不可能开源的,而且由于不同平台限制,以及摄影师对自身影响力传播的需要,摄影作品大部分面临版权问题,即使摄影师自己,也面临被平台限制的问题。而绘制作品主要是基于 PS 等绘图软件创作的成果,这类作品大部分都包含了比较重的创作成本,因此,有偿使用也是情理之中。大部分作品主要被放在素材平台上进行统一的版权销售,因此,我们需要注意。我们在绕过平台直接向作者购买图片时,也要注意作者是否和平台签订了排他性协议,如果平台强制要求作品只能由平台方进行版权销售,那么也要规避这类风险。

我所找到的可商用的免费图片平台包括:

pexels-免费高清素材下载网站

pexels 是非常知名的素材查找网站,很多设计师都会定期去查看。它上面提供大量素材,而且由于它上面的素材都是由其他创作者上传的,而非它自己收集的,并且遵循免费原则,因此,它上面的素材都可以免费使用。

pexels 高清图片素材网站

Unsplash-免费高清可商用摄影图片资源

unsplash 也是非常知名的摄影图片素材网站。它和 pexels 的不同在于,它上面有大量的人物摄影作品,而且同样支持免费商用,因此,可以作为需要模特出镜时的图片素材来源。

unsplash 高清人物摄影图片素材网站

pixabay-免费高清矢量图片资源

pixabay 也是一个知名的免费版权的图片资源网站,和前面两个不同的是,它还提供非常丰富的矢量图(插画),甚至还有视频资源可以下载。

pixabay 丰富的摄影、插画、视频素材网站

gratisography-免费高清创意图片资源

gratisography 也是一个知名的素材资源网站,也是免费版权的。不同于前面的网站,它上面的素材很多是经过处理好的,带有风格的成品。

gratisography 风格化高清图片资源网站

可以看出,大部分免费版权的网站提供的主要内容还是摄影作品,毕竟创作过程更快,可短时间内创作多张图片,但是,对于提供可编辑的插画而言,几乎都不感兴趣,毕竟成本很高。

字体

字体则是除了图片之外更容易发生版权纠纷的设计元素。因为几乎所有的设计作品中,一定会需要文字来进行适当的阐释,从而吸引用户的目光。对于出版物上的字体,实际上风险很大。前段时间爆出的微软雅黑版权问题,再度引发了行业对字体版权的重视。之所以字体版权维护更容易,是因为字体开发方可以在字体设计中刻意的加入特殊设计风格,因为字体都要透过系统输入来呈现出来,要修改系统中的字体非常麻烦,很难对所有字都进行重新创作,维权容易。因此,设计师在挑选字体时,一定要使用有版权,或免费版权的字体。目前我收集到的免费可商用版权字体有:

站酷系列字体 5 款

前几年在一次字体版权问题爆发之后由站酷网发布的完全免费可商用的“酷站高端黑体”打开了完全免费商用字体的大门,随后几年,酷站发布了:站酷快乐体、站酷酷黑体、站酷意大利体、站酷小薇 logo 体。加上之前的酷站高端黑体一共 5 款完全免费的字体。而且由于字体开源,还有人在快乐体基础上进行了修改,产生了其他衍生字体。

方正系列字体 4 款

方正的 4 款字体方正黑体、方正书宋、方正仿宋、方正楷体可以免费用于商业用途,但免费并不代表不需要授权,你需要向方正公司申请商业授权使用(意思是,对方公司可能拒绝你的申请),这样它可以限制你的使用范围,防止字体被用于不恰当的场景。

思源系列字体 4 款

Adobe 在线字体库 Typekityu 与谷歌一起正式发布了新款开源字体:思源黑体(Source Han Sans)。随后,Adobe 和 Goole 又在思源黑体基础上,开发了宋体版,即思源宋体

虽然由两家公司合作开发,但各自对这款字体的称呼却不一样,Adobe 称之为 Source Han Sans(思源黑体),而谷歌则称它 Noto Sans CJK(CJK:Chinese, Japanese, Korean),并纳入了 Noto pan-Unicode 字体家族。Noto 是 Google 发起的一项字体项目,遵循 SIL 字体版权协议。思源黑体支持以下字体粗细:ExtraLight、Light、Normal、Regular、Medium、Bold 和 Heavy。

在思源黑体基础上思源柔黑体思源真黑体这两款字体也被做出来,并且也是免费商用的。

文泉驿字体系列 5 款

文泉驿是一个开源汉字字体项目,由旅美学者房骞骞(FangQ)于 2004 年 10 月创建,集中力量解决 GNU/Linux 高质量中文字体匮乏的状况。目前,文泉驿已经开发并发布了第一个完整覆盖 GB18030 汉字(包含 27000 多个汉字)的多规格点阵汉字字库,第一个覆盖 GBK 字符集的开源矢量字库(文泉驿正黑),并提供了目前包含字符数目最多的开源字体——GNU Unifont——包含绝大多数中日韩文相关的符号。

目前主要的字体:文泉驿点阵宋体、文泉驿正黑、文泉驿点阵正黑、文泉驿等宽正黑、文泉驿微米黑、文泉驿 Unibit

明体系列 4 款

来自台湾的最活跃的字型社团「字嗨」管理员 But Ko ,释出三款改造自思源宋体的繁体中文字体,开放给需要的使用者免费下载!三款字体分别为:源样明体、源流明体及源云明体台湾明体cwTeXMing是一款旧字形外观,在一定程度上仿照古籍〈康熙字典〉字体。

台湾教育部字体 2 款

来自台湾教育部发布的两款字体,台湾教育部国字隶书台湾教育部标准字,都是繁体字,而且因为台湾仍然沿袭古体字,所以在一些输入上和大陆不同,你必须输入繁体才能正常显示对应的字,否则会显示方块。

其他字体

此外,除了上述这些字体之外,还有一些其他的字体也是商用免费的。例如刻石錄系列字体(刻石錄I.钢笔鶴体、刻石錄I.明体、刻石錄I.颜体)、cwtex-q-fonts、明朝体系列 3 款(花园明朝体、装甲明朝体和源界明朝体)等,但由于这些字体的制作方并没有特别出名,因此也常被忽略。有人整理了所有可以免费商用的字体,并且注明了版权协议:

在实际设计中,对于只需要对少数字进行使用时,可以模仿字体的思想,自己通过钢笔工具自己构造自己的文字。

图标

图标(icon)也是 web 设计的重头戏,但是要设计一套图标非常麻烦,而且不同的项目都要重新做一套图标,或者一个设计师对接不同项目时,要反复的拷贝自己以前的设计进行细节修改,会折磨设计师的思想。对于快速迭代的项目,挑选可商用的免费版权图标也是一个需要注意的问题。虽然网络上看到的图标(例如 Facebook 的 icon,例如一些常用的标志的 icon)看上去一致,但是实际在技术层面,作者都作了防盗版标记,因此,不可以随便乱用,两个相同的图标(可能长的一模一样)也可能存在陷阱,因此,一定要从授权网站下载授权图标。

我所知道的收刮免费商用版权的图标来源有:

undraw

undraw 一个提供完全免费的 SVG/PNG 图片素材的站点,网站由 KaterinaLimpitsouni 创建创办,该网站所有的素材图片遵循 MIT 协议许可(开源协议),网站不断更新 SVG 图像素材,并完全免费使用。

Flat Icon Design

一个日本的免费扁平化矢量图标网站,总数量大约有 500 个左右,设计风格简约,最重要的是免费可商用(在它的搜索框旁边已显著注明了可免费商用),下载格式包括:AI、EPS、JPEG、PNG、SVG。

Linea

Linea 由国外团队开发的一套黑白图标,有700+个,下载下来之后,有不同的分类。

Evil Icons

Evil Icons 是由外国的两名开发者联合设计师一起发布的库,同时支持图标的免费使用。你可以通过各种库安装工具下载它,也可以在github上下载源码自己编译。它是基于MIT开源协议完全免费的。

 

免费的 icon 字体库

包括bootstrap, font awesome 在内的一些库都提供了免费的 icon 字体版本。

Iconfinder

iconfinder 是一个图标平台,你可以在上面检索它所提供的图标,它提供了免费和付费的图标,付费图标需要支付后才可以下载,而免费的图标可以用于商业(在下载时可以看到旁边注明)。

虽然有很多提供免费下载图标的网站,例如阿里巴巴的 fonticon、easyicon 等网站,但是它们因为没有具体明确的版权信息,你不知道下载的 icon 是否经过了授权,因此,不建议直接使用从这类网站下载的 icon。

小结

web 设计本身是一件耗时耗力的创造性过程,不能因为在自己的作品中使用了未授权的素材而给自己带来长久的风险,开发者在快速开发自己的产品,设计师在设计自己的作品时,都应该避免一些陷阱,不要被“免费”二字所欺骗,一定要拿到具体的版权协议,并将所用到的素材所对应的版权协议版本和自己的作品放在一起,以证明自己使用了经过授权的素材。

本文所提供的这些资源,它们都提供比较直接的免费可商用版权,而没有刻意设置陷阱。其中几个是分了免费和收费的,但是都比较直接的,没有陷阱,收费和免费区分的非常清晰。你在使用时,也可以根据自己的需要进行付费购买,毕竟别人的设计成果还是需要金钱的支持才能激发他们继续提供更好的作品。

22:17:48 , , , 已有5条回复
  1. 最后我来推荐一个有良心的收费字体:喜鹊造字。

    比起方正的收费标准来说,喜鹊的收费简直是企业福音了。

    https://www.luckytype.com/
    #769 Betty 2019-04-22 19:39 回复
  2. 你确定没有收广告费?
    #770 回复给#769 否子戈 2019-04-22 22:23 回复
  3. 哈哈,因为公司付费买这些喜鹊字体时,都在感慨价格实惠。
    方正的报价简直了,而且还不是买了能随便用哦。
    记得站酷的报价我们之前也是去了解过,也是令人告辞。


    Unsplash,我以前在它上面不定期找壁纸来用。还蛮喜欢其风格的。
    #771 Betty 2019-04-22 22:36 回复
  4. 字体研发本身就是比较费钱的,所以做一套字体,拿来卖,收盗版费,基本上也是行业规则。
    有兴趣可以研究一下手写体,用画板写出来,然后通过软件自己分析,得到一套字体。
    #772 回复给#771 否子戈 2019-04-22 22:55 回复
  5. "有兴趣可以研究一下手写体,用画板写出来“

    别说,X 久前起就想过给自己弄个数位板之类的,但是又怕自己三分钟热度。
    虽然冤枉钱从来没少花,但……总有更吸引我花冤枉钱的点……
    #777 回复给#772 Betty 2019-05-01 23:31 回复

Unsplash

可免费商用的图片素材供应商。
https://unsplash.com/

思源宋体

思源宋体、思源黑体这两款字体都是开源免费(可商用)的高质量字体,由adobe发布,值得收藏。
https://source.typekit.com/source-han-serif/cn/

012019.4

JavaScript 算法

242019.3

手机端真机调试

https://segmentfault.com/a/1190000018613578

212019.3

文件名绝对不能使用驼峰命名方式,原因很简单,不同操作系统对大小写敏感程度不同,导致修改文件名之后无法被识别,git不对这些文件进行任何处理,但是你在代码里面又是使用新的文件名。等你部署的时候,代码报错说找不到这些文件。正确的文件名命名方式是使用-或_连接单词,但是也又一些命名为了省空间不使用连接符,全部小写,这样会导致一些单词连在一起之后,有歧义,而且说实话,工程项目,有的时候为了提升团队协作的整体效率而牺牲小部分性能,也是可以接受的,成熟的现代编程,会平衡代码开发时和运行时的体验,而非一味追求运行时体验。

15:24:15 已有0条回复