这种水印的实现其实是比较简单的,就是将两张图片合成一张,或者是直接在原图上绘制内容就行了,对应的 HTML 代码:
<imgid="pic"src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f3c3c98ebfce4ae28db981dfabedc1d8~tplv-k3u1fbpfcp-zoom-1.image"alt="原始图片"height="500"crossorigin="anonymous"><div>Photo by Claudio Schwarz | @purzlbaum on Unsplash</div>
对应 JavaScript 代码:
window.onload=()=>{constpic=document.querySelector('#pic');constcanvasNode=document.createElement('canvas');constpicWithWatermark=createImageWithWatermark(pic,canvasNode);pic.src=picWithWatermark;}/** * 创建带水印的图片 * create image with watermark. * @param{HTMLImageElement}img 图片结点 - image element. * @param{HTMLCanvasElement}canvas canvas结点 - canvas element. * @returns 处理后的图片 base64 - pic with watermark. */constcreateImageWithWatermark=(img,canvas)=>{constimgWidth=img.width;constimgHeight=img.height;canvas.width=imgWidth;canvas.height=imgHeight;constctx=canvas.getContext('2d');ctx.drawImage(img,0,0,imgWidth,imgHeight);ctx.font='16px YaHei';ctx.fillStyle='black';ctx.fillText('Photo by Claudio Schwarz | @purzlbaum on Unsplash',20,20);returncanvas.toDataURL('image/jpg');}
历史上,canvas 最早是由 Apple Inc. 提出的,在 Mac OS X webkit 中创建控制板组件使用,而在 canvas 称为 HTML 草案及标准之前,我们是通过一些替代方式去绘图的,比如为人所诟病的 Flash,以及非常强大的 SVG(Scalable Vector Graphics,可伸缩的矢量标记图),还有只能在 IE(IE 5.0以上的版本)中使用的 VML(Vector Markup Language,矢量可标记图)。甚至于有些前端可以使用 div+css 来完成绘图。
DNS 是一个协议,用于域名 URL 到 IP 地址的映射,或者说是根据 URL 去查询 IP 地址。
在 Windows 下,我们可以在 C:\window\system32\drivers\etc\ 目录下找到一个 hosts 文件,这个文件记录了 URL 到 IP 的转换,通常来说,我们不需要手动去修改这个文件,而是在网络协议中配置 DNS 服务器,通过 DNS 查询完成 URL 到 IP 的转换。
浏览器访问网站需要查询 URL 对应的 IP 地址,而网站的接口也需要进行查询 IP,首先浏览器在 DNS 请求过程中等待,什么都不做,这时候浏览器只能保持白屏 100ms,而在后续的接口请求中,我们还要进行 DNS 查询,这样的等待是没有意义的,而且这对 DNS 服务器带来的压力也不小……
但是在加了 DNS 缓存后,我们就可以直接在缓存中找到 URL 对应的 IP,省去了等待时间,响应速度一下就上去了。
通常,DNS 查询的时间在 20ms 左右。
现在的浏览器都实现了 DNS 缓存,不过采用的方式是不同的,至于具体采用了啥方式,这个我也不知道了,不过有一点,IE 设置了30分钟的缓存时间,Chrome 和 FireFox 则是设置了1分钟的 DNS 缓存有效期。但无论是30分钟还是1分钟,时间长短并不是区分其优劣性的因素。 时间设置的短:那么浏览器就对IP变化敏感,可以保证请求是正确的。 而时间设置的长了:那么就可以避免重复请求 DNS 服务器,节省时间。
NOTE:还有一个协议需要了解,就是 ARP 协议(地址解析协议),我们在得到了 IP 之后,需要进行 TCP 握手,这一步需要找到 MAC 地址,而 ARP 协议的作用就是 IP 到 MAC 的映射。
exportclassSomeimplementsOnInit{ngOnInit(){// *. 做一次类型转换,或者做类型断言letdom=<HTMLInputElement>document.getElementById('infoArea'); let dom1 = document.getElementById('infoArea') as HTMLElement; // 1. 获取输入框中的内容 let html = dom.innerHTML; let val = dom.value; // 2. 打印输出 console.log(html); console.log(val); }}
总结
HTMLElement 是 DOM 结点共有的属性,TypeScript 库中抽取该属性作为一个公共接口,类似于其他面向对象语言如 Java 和 c++ 中所说的基类。这样做可以保证在操作 DOM 结点的时候不会出现访问不存在属性的问题。
HTMLInputElement 是 HTMLElement 的一个子接口(或说子类,但 TypeScript 是支持 class 的,所以说接口更好一些),其内部封装了如 input,textarea 这类 dom 结点的属性。