Typescript *.ts 文件中引入图片时报错,没有正确的类型声明

webpack 都配置完成,但在 ts 文件中引入图片时报错,此时需要在全局 d.ts 文件中增加以下声明

// 全局d.ts文件中,增加声明
declare module "*.svg";
declare module "*.png";
declare module "*.jpg";
declare module "*.jpeg";
declare module "*.gif";
declare module "*.bmp";
declare module "*.tiff";

// 这样引入图片时就不会报类型错误了
import Img from "../xxx.png";

前端框架时代,越来越多的网站成为了单页应用,路由被前端接管,切换到新的路由,只要请求 json 数据就可以了,但随之而来,也产生了一个问题:上一个路由发出的请求还未收到响应,下一个路由又发了新的请求,而旧请求响应在新请求的响应后才到达,就会发生本应该使用新响应数据的视图却最终使用了旧响应的数据,导致内容文不对题的情况发生。

解决这个问题的思路乍一想也很简单,在路由切换时,取消所有尚未返回响应的请求即可,但现实并非如此。

Read more »

使用 fetch

fetch 与 XMLHttpRequest 实现的 jQuery.ajax() 有以下三点不同:

  • 当接收到一个代表错误的 HTTP 状态码时(即使响应的 HTTP 状态码是 404 或 500),从 fetch 返回的 Promise 不会被标记为 reject。它会将 Promise 状态标记为 resolve(但是会将 resolve 返回值的 ok 属性设置为 false),仅当网络故障时或请求被阻止时,才会标记为 reject;
  • fetch 可以接受跨域 cookies;
  • fetch 默认不发送 cookies,除非你使用了 credentials 选项;
fetch("http:// example.com/movies.json").then(function (response) {
  return response.json();
});

fetch() 获取到的只是一个 HTTP 响应,而不是真正的 JSON,为了获取真正的 JSON 内容,需要使用 json() 方法。

Read more »

d.ts 中使用 import 语法,导致全局类型失效问题

一个常见的应用场景,即我们需要扩展 window 全局变量,但 window 的类型声明不包括我们新增的属性,故会通过在全局的 d.ts 文件中书写 window 的 interface 来给 window 增加新的属性,当新属性的类型引用到某个导出的类型时,就要使用 import 语法导入这个类型,一旦使用 import 语法,d.ts 文件就从默认全局转为了默认模块。如何解决全局类型失效的问题呢?

使用 global 的 namespace 即可

// 使用三斜线语法引入类型,该d.ts文件还是全局,但这个文件本身引用不到/ref-path下的类型
/// <reference path="/ref-path">
interface window {
  prop: MyType; // Error 虽然MyType在/ref-path下,但该文件中还是读取不到
}

// 使用import语法引入类型,该d.ts文件默认转为模块,需要使用global命名空间来使某些声明成为全局
import { MyType } from "/ref-path";
declare global {
  interface window {
    prop: MyType;
  }
}

参考资料

*.d.ts 导入 import 其它类型导致全局类型失效问题

Typescript 入门教程

表单 Form.Item 只会对它的直接子元素绑定表单功能

例如 Form.Item 直接包裹了 Input/Select。若是在 Input 等控件前后还有文案或样式装点,抑或是控件是经过条件判断后再直接包裹的,都无法自动绑定表单功能。还需要使用内嵌的 Form.Item 来完成表单功能。可以在 Form.Item 上添加 noStyle 属性作为无样式的绑定组件。

// 有文案或样式的情况
<Form.Item label="Field">
  <Form.Item name="field" noStyle><Input /></Form.Item> // 直接包裹才会绑定表单
  <span>description</span>
</Form.Item>
// 有条件判断的情况
<Form.Item label="Field">
  {condition ? <Form.Item noStyle><Input /></Form.Item> : <Form.Item noStyle><Select /></Form.Item>}
</Form.Item>

参考官方文档

几种 version 相关的 npm 命令

# 通过命令变更package.json中的版本号
npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git]
# 查看当前npm版本
npm [-v | --version]
# 查看某个已发布包的版本号
npm view <pkg> version
# 查看当前目录下所有包与依赖的版本
npm ls #还可以使用--depth=<number>参数来选择查看的目录层级
Read more »

背景介绍

DOM 元素的属性或节点变化的监测,可以使用 MutationObserver 对象,但若想要检测 DOM 元素尺寸变化,过去是没有可以直接使用的 API 的,多是借助 window 对象上绑定 resize 事件。

但这种方式是有缺陷的,有时候 DOM 元素尺寸变化了,但 window 尺寸并没有变化,就监听不到;还有时候 window 尺寸变化了,但 DOM 元素尺寸并没有变化,在 window 上绑定 resize 事件就浪费性能。

基于这样的使用背景,就出现了新的 API ResizeObserver。这个 API 使用了观察者模式,专门用来监听:

  1. 某个节点的出现和隐藏;

  2. 某个节点的尺寸变化;

该 API 较新,chrome、firefox 最新版均已支持,而 safari 也确认未来会支持。使用 polyfill 可以兼容至 IE11。

Read more »

原始类型与引用类型

JavaScript 虽然没有类的概念(ES6 后增加了 class 语法糖,但本质上还是通过原型实现的),但依然存在两种类型:原始类型和引用类型。

  • 原始类型保存为简单数据值;
  • 引用类型则保存为对象,其本质是指向内存位置的引用;

为了让开发者能够把原始类型和引用类型按相同方式处理,JavaScript 花费了很大努力来保证语言的一致性。

其他编程语言用栈储存原始类型,用堆储存引用类型。JavaScript 则完全不同:它使用一个变量对象追踪变量的生命周期,原始类型的值被直接保存在变量对象内,而引用类型的值则作为一个指针保存在变量对象内,该指针指向实际对象在内存中的存储位置。

原始类型

JavaScript 共有 5 种原始类型:boolean number string null undefined。所有原始类型的值都有字面形式。原始类型的变量直接保存原始值。

鉴别原始类型的最佳方法是使用 typeof 操作符。它可以被用在任何变量上,并返回一个说明数据类型的字符串。

需要注意的是当运行 typeof null 时,结果是’object’,其实这已经被设计和维护 JavaScript 的委员会 TC39 认定是一个错误,但出于向前兼容的需要,并未修改。在逻辑上可以认为 null 是一个空的对象指针,所以结果为’object’。判断一个值是否为空类型的最佳方法是直接和 null 比较value === null

非强制转换比较
=== 在进行比较时不会将变量强制转换为另一种类型,所以比较 undefined 和 null 时,== 认为它们相等,而 === 认为它们不相等。

虽然字符串、数字、布尔是原始类型,并不是对象,但它们也拥有方法(null 和 undefined 没有方法)。JavaScript 使它们看上去像对象一样,以此来提供语言上的一致性体验。

引用类型

引用类型主要指 JavaScript 中的对象,同时也是该语言中最接近类的东西。我们既可以使用 new 操作符和构造函数的方式来创建对象,也可以使用字面量的形式创建对象。任何函数都可以是构造函数,根据命名规范,JavaScript 中的构造函数用首字母大写跟非构造函数进行区分。

引用类型不在变量中直接保存对象实例,而是一个指向内存中实际对象所在位置的指针(或者说引用)。当一个对象赋值给变量时,实际是赋值给这个变量一个指针。这意味着将一个变量赋值给另一个变量时,两个变量各获得了一份指针的拷贝,指向内存中的同一个对象。

参考资料

leaflet 加载 arcgis 切片

LeaFlet 中切片图层使用自定义坐标系

leaflet 系列二 加载 arcgis 自定义坐标系服务

在 Leaflet 中自定义 4490 坐标系

EPSG Geodetic Parameter Dataset

前置条件

  • google 邮箱(其他支持代发的邮箱也可)

  • namesilo 域名(其他支持设置邮件转发的域名商也可)

一、通过域名服务商设置邮件转发

进入 namesilo 域名管理页面,选择 Email forwarding 的 config 选项,设置自定义的用户名与要转发到的 google 邮箱。

二、添加邮箱解析,设置 MX 记录

进入 namesilo 域名管理页面,选择 DNS 管理页面,添加默认的 Email forwarding 模板,即可生成 namesilo 默认的 MX 记录。还可以设置 TXT 的 SPF 记录以防止被仿冒。新建 TXT 记录,设置值为 v=spf1 include:_spf.google.com ~all。

完成这两步后,以你域名与自定义用户名为邮箱地址的邮箱就可以接收邮件并转发至你的 google 邮箱了。

那么如何使在发信时也使用这个自定义邮箱呢?

三、使用 Gmail 从自定义邮箱发送邮件

进入 Gmail 邮箱设置——账号和导入——用这个地址发送邮件,添加自定义域名地址,smtp 服务器则填写 smtp.gmail.com,再填入 google 邮箱密码即可。这一步可能需要降低 google 安全级别才能成功。因为 google 不推荐使用 smtp 形式发送邮件。这一步本质上还是在用 google 的邮箱服务发送邮件,只是发件人替换成了自定义的邮箱地址。设置完成后会在 google 邮箱中收到确认邮件,确认后就可以用自定义域名发送了。如果要默认使用自定义域名发送邮件,则继续回到账号和导入设置界面,将刚刚添加的地址,设置为默认即可。

box-shadow

box-shadow属性用于在元素上添加阴影效果。同一个元素上可以设置多个阴影效果,使用逗号将它们分开即可。该属性可设置的值包括x轴偏移量(x-offset),y轴偏移量(y-offset),模糊半径(blur-radius),扩散半径(spread-radius),颜色(color)。

若元素设置了border-radius属性,阴影同样会有圆角效果。多个阴影在z轴上的顺序和text-shadows规则相同,即第一个阴影在最上面。

box-shadow属性值设置规则

  • 二至四个值时

    • 二个值时,被视为offset-x与offset-y

    • 三个值时,第三个值为blur-radius

    • 四个值时,第四个值为spread-radius

  • inset 可选值,表示阴影向内

  • color 可选值,指代阴影颜色

取值

inset 未指定inset时阴影默认向外扩散,使用inset关键字使阴影落在盒子内部,看起来像是内容被压低了,此时阴影在边框之内,背景之上,内容之下。

offset 两个offset为length类型值。用来设置阴影偏移量。offset-x 设置阴影水平偏移,正值阴影位于元素右边,负值阴影位于元素左边。offset-y 设置阴影垂直偏移,正值阴影位于元素下方,负值阴影位于元素上方。

blur-radius 必需为正值,设置阴影模糊面积,越大阴影颜色越淡。默认为0,阴影边缘锐利。

spread-radius 默认为0,阴影与元素同样大小。取正值时,阴影扩大,取负值时,阴影收缩。需要考虑inset属性的影响。

color 未指定时由浏览器决定,通常为color的值,safari中为透明。

Photoshop投影与css阴影的换算

结构:

  • 混合模式:Photoshop提供了各种混合模式,css仅支持正常模式

  • 不透明度:相当于box-shadow中color的rgba中的a值

  • 角度:投影的角度

  • 距离:阴影的距离,根据角度和距离可以换算出css3中的offset-x与offset-y

    • offset-x:距离 * cos(180度 - 角度)

    • offset-y:距离 * sin(180度 - 角度)

  • 扩散:阴影的扩散,根据扩散与大小可以计算出spread-radius与blur-radius

  • 大小:阴影的大小

    • spread-radius:扩散 * 大小

    • blur-radius: 大小 - 扩散 * 大小

text-shadow因为没有spread-radius所以不能完全实现Photoshop中的效果。

0%