Zong
2018 / 秋

杭州已经入秋,天气逐渐转凉,记得添衣噢

今年国庆,我依然没有放过假期,前往台湾旅游(图摄于台湾垦丁)

接下来来分享一下,9月的一些收获(水水更健康)

轻量级 domManip 函数

要说到 domManip 函数,相信读过 jQuery 源码的同学,都多多少少对这个函数有些印象。在之前的博客中,我有提到 jQuery html API 与 原生 innerHTML API 这一话题。

考虑PAJAX方式替换页面内容,发现原生 innerHTML API替换DOM内容后,不会自动执行 <srcipt> 标签,但是jQuery html API实现了这一点。那时的我,很无奈的选择了引入了 jQuery,因为项目是基于 Vue 的,由于我的代码洁癖,我并不希望引入 jQuery。所以想着等读完 jQuery 源码后,尝试的去移除 jQuery,手写一个实现。

首先实现执行 script 的函数,之前博客也有提到过,源码很简单:

const evalSrcipt = text => {
  // 创建 script 标签
  const s = document.createElement('script')
  // 将入参 text 也就是 JavaScript 语句塞入 script 标签中
  s.textContent = text
  // 将 script 标签插入 body 以执行 JavaScript
  document.body.appendChild(s)
  // 将这个 script 标签从 body 中移除
  document.body.removeChild(s)
}

然后来实现一个轻量级 domManip 函数,我这里并没有 Sizzle CSS Selector Engine,所以我只对 id 下手,接下来请看源码:

const domManipLight = (idNode, text) => {
  // 获取入参 idNode 设置根节点
  const root = document.getElementById(idNode)

  // 判断入参 text 是否为空,若为空直接将根节点置空
  if (text === '') {
    return root.innerHTML = text
  }

  // 主角登场:document.createDocumentFragment()
  // DocumentFragments 是DOM节点。它们不是主DOM树的一部分。通常的用例是创建文档片段,将元素附加到文档片段,然后将文档片段附加到DOM树。在DOM树中,文档片段被其所有的子元素所代替。
  // 因为文档片段存在于内存中,并不在DOM树中,所以将子元素插入到文档片段时不会引起页面回流(对元素位置和几何上的计算)。因此,使用文档片段通常会带来更好的性能。
  const documentFragment = document.createDocumentFragment()
  // 为文档片段插入 div 标签
  documentFragment.append(document.createElement('div'))
  // 获取这个 div 标签
  const div = documentFragment.children[0]
  // 在这个文档片段的 div 标签下使用 innerHTML 方法替换页面内容
  div.innerHTML = text
  // 在根节点下使用 innerHTML 方法替换页面内容,并不会执行 script 标签下的内容
  root.innerHTML = text
  // 从文档片段的 div 标签下检索 script 标签
  const srcipt = div.getElementsByTagName('script')
  // 遍历文档片段的 div 标签下的 script 标签
  for (const i of srcipt) {
    // 判断若 script 标签存在 text 值,则直接调用 evalSrcipt 函数
    if (i.text) {
      evalSrcipt(i.text)
      // 判断另一种情况,若script 标签存在 src 属性,则 AJAX 请求该 src 属性值,将返回值传入 evalSrcipt 函数执行
    } else if (i.src) {
      AJAXGetPage(i.src).then(text => evalSrcipt(text))
    }
  }
}

重新认识 change 事件和新认识 SyntheticEvent

为什么会提到这一点呢,群里面聊起了 Vue 下的 <input> 标签的 change 事件。实践中,你会发现 <input> 标签的 change 事件并不会在每次元素值的更改而触发。那么问题也就来了,这和 <input> 标签的 blur 事件产生的效果真的好像。查阅 MDN 发现,与 input 事件不同,change 事件不一定会对元素值的每次更改触发。

看到这点使我很惊讶,因为我回忆 <input> 标签的 change 事件在 React 中的表现并不是这样的,确实事实如此,React 中有一个很有意思的关键词出现了 SyntheticEvent

我们先来重新认识下 change 事件,事件触发取决于表单元素的类型(type)和用户对标签的操作:

  • <input type="radio"><input type="checkbox"> 的默认选项被修改时(通过点击或者键盘事件);
  • 当用户完成提交动作时 (例如:点击了 <select> 中的一个选项,从 <input type="date"> 标签选择了一个日期,通过 <input type="file"> 标签上传了一个文件,等 );
  • 当标签的值被修改并且失焦后,但并未进行提交 (例如:对 <textarea> 或者 <input type="text"> 的值进行编辑后。).

重点出现了,“当标签的值被修改并且失焦后”,所以在前面会觉得这和 <input> 标签的 blur 事件产生的效果真的好像。

那么为什么 React 中 change 事件的表现却是 当标签的值被修改后 而非 并且失焦后,那是因为 SyntheticEvent

您的事件处理函数将会接收 SyntheticEvent 的实例,一个基于浏览器原生事件的跨浏览器实现。它拥有和浏览器原生事件一样的接口,包括 stopPropagation()preventDefault() ,除了那些所有浏览器功能一样的事件。

SyntheticEvent 中会提到另外一个概念 Event Pooling(事件池):SyntheticEvent 是共享的。那就意味着在调用事件回调之后,SyntheticEvent 对象将会被重用,并且所有属性会被置空。这是出于性能因素考虑的。 因此,您无法以异步方式访问事件。

关于 SyntheticEvent 的实现,可以 Google 一下啦,看一些源码解析类的文章即可,在浅析 jQuery 以后,有机会可以浅析 React 和 Vue。

Securing your GitHub Pages site with HTTPS

HTTPS adds a layer of encryption that prevents others from snooping on or tampering with traffic to your site. You can enforce HTTPS for your GitHub Pages site to transparently redirect all HTTP requests to HTTPS.

All GitHub Pages sites, including sites that are correctly configured with a custom domain, support HTTPS and HTTPS enforcement. For more information about custom domains, see “Using a custom domain with GitHub Pages.“ For information about troubleshooting HTTPS with custom domains, see “Troubleshooting custom domains.

HTTPS enforcement is required for GitHub Pages sites using a github.io domain that were created after June 15, 2016. If you created your GitHub Pages site before June 15, 2016, you can manually enable HTTPS enforcement.

Tip: GitHub Pages sites shouldn’t be used for sensitive transactions like sending passwords or credit card numbers.

Enforcing HTTPS for your GitHub Pages site

1.On GitHub, navigate to the main page of the repository.

2.Repository settings buttonUnder your repository name, click Settings.

repo-actions-settings

3.Enforce HTTPS checkboxUnder “GitHub Pages,” select Enforce HTTPS.

enforce-https-checkbox

HTTPS errors

GitHub Pages sites using custom domains that are correctly configured with CNAME, ALIAS, ANAME, or A DNS records can be accessed over HTTPS. For more information, see “Securing your GitHub Pages site with HTTPS.

It can take up to an hour for your GitHub Pages site to become available over HTTPS after you add and correctly configure your custom domain. After updating existing DNS settings, you may need to remove and re-add your custom domain to your GitHub account to trigger the process of enabling HTTPS. For more information, see “Using a custom domain with GitHub Pages.

If you’ve chosen to use Certification Authority Authorization (CAA) records, at least one CAA record must exist with the value letsencrypt.org for your GitHub Pages site to be accessible over HTTPS. For more information, see “Certificate Authority Authorization (CAA)“ in the Let’s Encrypt documentation.

Custom domains configured with A records

If you configured your custom domain using an A record, your A record must point to one of the following IP addresses for HTTPS to work:

  • 185.199.108.153
  • 185.199.109.153
  • 185.199.110.153
  • 185.199.111.153

After updating any A record IP addresses, you must remove and re-add your custom domain to the repository you’re using to publish your Pages site to trigger the process of enabling HTTPS. For more information, see “Configuring A records with your DNS provider” in “Setting up an apex domain.

简单谈谈交互设计

为什么要谈谈交互设计呢,因为这次项目小版本升级中,我似乎主动的对交互设计起了点兴趣,再者你会发现其实 Web 开发中交互无处不在(Why web developers need to care about interactivity),论你的 Web 项目用户体验是如何如何,都可以从交互中感受到。

interactivity

那么什么是交互设计呢?交互设计,又称 互动设计,(英文Interaction Design, 缩写 IxD 或者 IaD),是定义、设计人造系统的行为的设计领域。人造物,即人工制成物品,例如,软件、移动设备、人造环境、服务、可佩带装置以及系统的组织结构。交互设计在于定义人造物的行为方式(the “interaction”,即人工制品在特定场景下的反应方式)相关的界面。

交互设计师首先进行用户研究相关领域,以及潜在用户,设计人造物的行为,并从有用性,可用性和情感因素(usefulness, usability and emotional)等方面来评估设计质量。

所以在此你会发现 Web 开发与交互设计两者一直是在一起的,作为一位 JavaScript 开发者利用语言来实现交互是一件很有魅力的事情,包括自己去设计交互。

对了,还需要说一下关于设计。(转载 《什么是设计?设计的本质是什么?》)

  • 设计可以让更多生命得到温饱,让生态进入合理的循环;
  • 设计提高社会和程序的运行效率,节省人们更多时间,间接延长了人们的寿命;
  • 设计给人们带来更好的精神体验,提高人们的修养,让人变得智慧善良,减少人类的内耗。
  • 设计在改善世界。每一件美好的充满智慧的事情都在告诉我什么是设计。

总之,设计就是改善。每个人都可以做。

相关链接