ssh

ssh 的一点使用记录

最近一直玩手游,看小说。估计快修仙了。废了。不过也抽空买了个 阿里云ecs,补习JS,准备捣鼓一下。

操作,遂记录如下。

  1. 配置不提,系统选的是CentOS。拿到公网IP,(是否通过企业级NAT,管不了那么多了。)能连接就行了。
  2. 我怎么弄得root初始密码,也记不清了。哎,拖到今天,不能复现当时情况了。应该是 阿里云的控制台 重置的吧。
  • 网页也可以登录,从控制台那里找到实例,远程连接。需要输入六位的网页密码,第一次登录会给你。也可以重置,手机验证。然后是网页中的黑屏,输入用户名,密码即可。(似乎在console看到了WebSocket。)
  • windows下可以用 putty,ssh登录,端口22是默认开启的。如果你当时选系统Windows,可以用远程桌面连接,端口3389默认开启的。
  1. ssh的密码登录不提,我这里想使用的是 Public Key登录。
  • 生成秘钥。 安不安全不提,无所谓在哪里生成 秘钥,关键是要拿到自己手里。你可以在自己的机器上生成。我是在密码登录了远程机,然后生成的。
    • 直接 ssh-keygen,连 -t rsa 都不用。
    • 一路回车,如果你需要给 Private Key 设置密码,你就设置一个记住就行。
    • 完事后就得到 Key Pair(Public Key 和 Private Key),默认就是 .ssh/id_rsa.pub,.ssh/id_rsa 两个文件。 我是在远程机上操作的(不推荐),我把这两文件赶紧弄到我本地机子上藏了起来。
  • 把公钥弄到远程机上。我本来就在远程机上生成的,这一步倒是免了。win7可以用putty带的psftp传。
    • 在远程机器上,把 id_rsa.pub 放到你的 /home/你的用户名/.ssh文件夹。难道你想放到别人的 .ssh目录中?
    • 然后 把 id_rsa.pub 的内容追加到 authorized_keys 文件中。如果不存在就建立。 touch authorized_keys。操作都在你的 .ssh目录。
    • 可以说就完了。就这么简单。 我然后把id_rsa.pub删除了,这都随你。我也没啥经验。
  1. 远程机的管理员需要设置。
  • /etc/ssh/sshd_config,设置PubkeyAuthentication yes。
  • service sshd reload。 重载ssh服务配置。

普通用户就是上面第3步。没其他多余操作。需要注意的是 .ssh目录的权限要设置为700,authorized_keys文件, u权限rw, g和o权限最多r,设置为600即可。具体man sshd(我没看过)。

该连接了,我是用的手机

  1. 方法一,我就打开了 阿里云app,进入控制台,选择ssh工具,添加主机,设置秘钥对连接,但是死活登录不上去。
  2. 方法二,后来,我进入app,控制台,在我的云产品中选择云服务器ECS,右侧的三个小点点,点击有ssh连接,用秘钥对连接,然后就连上了。
  3. 从此以后用方法一也可以连上了。

这是什么骚操作,我也理解不了。

the-coming-plan

  1. 接下来准备学习一下算法
  2. 加强锻炼
  3. 时间不多了。尽管已经老了,可我从来没觉得自己老了。也不知道自己这么多年干了什么。东一榔头,西一棒槌。
  4. 不怎么喜欢看书。小时候就觉得假东西太多,尤其是政治书,还讨厌背东西。我很多年的想法是宁愿不学,而且害怕学到一堆错误的东西。所以,数学那些还是很喜欢,可惜,我如果不能浏览一遍全书,我是一道题目都不太愿意去做的。这个习惯,就像单身一样,一直保持。搞计算机这几年,也是吃了这个大亏,很少动手去写。如果克服不了这些,这辈子可能就完了。
  5. 啥都没有,就是时间多(闲)。不想白来人世间一趟。

runtime-JavaScript

别说话,运(wen)行(wo)

wwWorld
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var ILoveU = 'are you kidding?';

function helloWorld(argc, argv){
"use strict";

var BBC = "2B";

function worldCup2018 () {
var no10 = "Messi";
return BBC;
}

worldCup2018();

return null;
}

helloWorld(1, "holy shit!");

人狠话不多,直接放狗,噢……放图。想想之前自己的图,也有很多东西不能确定是否准确,但愿你能找到其中正确的,抛弃错误的。欢迎猛喷,只要你更有理,更有证据、实例。

  1. 这张图,我想做一些简化。

但是,这里有些名字,你是访问不到的,是由JS引擎来使用的。比如浏览器中,全局环境,this===window,但是没有Global(我之前用的Chrome调试器,截图出来,有这个东西,人家调试器就是能访问更多的信息;我就是不行,我就只能调用调用函数、API,抄抄代码)。node中,全局环境,this===global,也没有Global。比如全局环境中JS引擎也维护了一个Scope(或者叫其他名字),你是别指望拿到了。定义的函数的[[Scopes]],除非JS引擎暴露出来,你也别想访问。这个图,我也不知道怎么画才好。比如这篇文章变量对象,就认为:

全局上下文变量对象GlobalContextVO,(VO === this === global)

虽然它讲的很多东西都是基于ECMA-262-3的,但是直到现在很多基础的东西还是没变,有的是概念名字变了,猫叫个咪,有的是语法糖,有的的确是发展出了新的东西。同样,全局环境中,Object.getOwnPropertyDescriptor(this, 'this') === undefined,根本没有this这个属性;this是keywords,我这图里也不知道把它放哪里!我太心虚了,都不知道在解释什么了。

我想了想觉得还是这张图好点。

  1. 啊,不要停……不要停,继续运行,越过首行,一眨眼,就18岁了,不,就到18行了。停!!!

这是越过首行受到的惩罚。

  1. 尝试越过18行,咦,我擦,怎么跑到第6行咧?

注意,现在我们到了helloWorld-ECthis: undefined,如果18行window.helloWorld(1, "holy shit!");this: window,你可以用其他对象也无所谓。Scope是个数组形式,第一个元素是Local,第二个元素是Global。(不知道怎么画数组)。Local中有参数值,变量定义,函数定义,还有arguments(这个对象是一个数组形式,包含实际传入的参数值,参数个数……图中没有画清楚,可以说是错误的。arguments[0]和argc之间又微妙的关系。应该画一个图形来表示这个对象,而且它的原型是Object.prototype)。Scope是由当前环境Local和产生当前环境的函数helloWorld的[[Scopes]](其中恰好含有一个元素Global)构成。

我又把这图改进了一下,arguments的__proto__,函数对象的__proto__,prototype也都没有画出来。
假设我们从helloWorld-EC返回到了global-EC,如果返回值是worldCup2018这个函数,并且我们用一个变量接受此值,(返回其他对象也可以,不过如果你返回arguments,接受它,你就arguments那么大块内存;返回函数的话,它的[[Scopes]]大的超乎你的想象!嘿嘿)那么可以看到,虽然我们从helloWorld-EC返回到了global-EC,虽然helloWorld-EC走了,但是worldCup2018依然活着,它的[[Scopes]]所引用的对象当然也在(这涉及到GarbageColletion,我也不懂),也就是这块内存还在用,也就是可以访问。

  1. 既然来了,那就运行第6行

哎,真详(啰)细(嗦)。

  1. 终于等到你……13多么伟大的数字啊!运行它。又飞到了第9行

注意,现在我们到了worldCup2018-ECthis: undefinedScope是个数组形式。

  • 本地环境Local,我画出了no10, arguments
  • 另一部分是函数worldCup2018的[[Scopes]],其中有两个元素。一个是 helloWorld-ECLocal环境,一个就是Global
  • 可以看到Scope中画出去了三条线,我这里的画法,没能体现它们之间的顺序关系,真是抱歉。

到此为止,往下画也没有意义了。

至于出栈的时候,一般就是返回到上一层环境合适的位置,比如此被调用函数的下一条语句。(调用函数时,要记得返回的位置。当然这个不是我要考虑的事情。)退到上一层环境时候,内环境中的对象怎么办?如果被引用,就不释放。这些对象,都是在堆上分配的;Call Stack也应该是在堆上模拟的。像C语言中的函数调用,用栈传参数值,记录返回地址……小弟只能说,干脆直接简洁。因此也没有JS函数很多特性(不能嵌套定义函数啊,啊,啊,啊……)。但是,学好数据结构,照着ECMA-262,就可以用C实现JS引擎(这也是小弟努力的目标之一)。就扯到这里吧,太阳都快下山了。下次我们粗解一下立即执行函数。每当调用一个函数,就想想,它的[[Scopes]]是什么,prototype是什么之类的。凡事都有例外,比如new Function(...)产生的函数对象,它的[[Scopes]]只含Global,和产生时所处的环境无关;with语句也会在环境中产生对象,那么此对象的原型是什么?暂时此对象放在哪里?;eval也是很奇特。等有空了,我去网上把答案研究(抄)过来。突然想到克罗地亚没夺冠,不好受。

JavaScript-prototype

先了解一点JavaScript知识(复制粘贴大法)

  1. ECMAScript is based on several originating technologies, the most well-known being JavaScript (Netscape) and JScript (Microsoft).

  2. ECMAScript is object-based: basic language and host facilities are provided by objects, and an ECMAScript program is a cluster of communicating objects. In ECMAScript, an object is a collection of zero or more properties each with attributes that determine how each property can be used—for example, when the Writable attribute for a property is set to false, any attempt by executed ECMAScript code to assign a different value to the property fails. Properties are containers that hold other objects, primitive values, or functions. A primitive value is a member of one of the following built-in types: Undefined, Null, Boolean, Number, String, and Symbol; an object is a member of the built-in type Object; and a function is a callable object. A function that is associated with an object via a property is called a method.

  3. Even though ECMAScript includes syntax for class definitions, ECMAScript objects are not fundamentally class-based such as those in C++, Smalltalk, or Java. Instead objects may be created in various ways including via a literal notation or via constructors which create objects and then execute code that initializes all or part of them by assigning initial values to their properties. Each constructor is a function that has a property named “prototype” that is used to implement prototype-based inheritance and shared properties. Objects are created by using constructors in new expressions; for example, new Date(2009, 11) creates a new Date object. Invoking a constructor without using new has consequences that depend on the constructor. For example, Date() produces a string representation of the current date and time rather than an object.

Every object created by a constructor has an implicit reference (called the object’s prototype) to the value of its constructor’s “prototype” property. Furthermore, a prototype may have a non-null implicit reference to its prototype, and so on; this is called the prototype chain. When a reference is made to a property in an object, that reference is to the property of that name in the first object in the prototype chain that contains a property of that name. In other words, first the object mentioned directly is examined for such a property; if that object contains the named property, that is the property to which the reference refers; if that object does not contain the named property, the prototype for that object is examined next; and so on.

  1. ECMAScript Language Type
  • The Undefined Type
  • The Null Type
  • The Boolean Type
  • The String Type
  • The Symbol Type
  • The Number Type
  • The Object Type
    数据类型就这七种(早些时候没有 The Symbol Type,未来会不会加入其他Type?我说错了你可以来打我)。对我们来说,重要的是值(Value),比如undefined,null,true,false,”美女”,{老婆:false},function 老婆 (many){return “2B”;}。

举个栗子,var b = "呵呵"; var bb = new String("别BB");

  • b,它的值 "呵呵",是字符串,The String Type。
  • bb,它的值 {...},是对象,The Object Type;但是呢,bb[0]=”别”,bb[1]=”B”,bb[2]=”B”,也就是说bb中的”别BB”是字符串,The String Type。
  • new String中的String仅仅是constructor,和The String Type中的String没毛线关系。
  • 类型转换不小心就会发生,自己得注意到底是什么Type。

再说prototype

网上有张图,很牛逼。 官方网址,里面有大图,可以打印出来。

为毛是这种关系? typeof Function.prototype === "function",这又是为毛?

假定我们就运行下面的代码

prototype就用这位前辈的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function Foo() {
this.value = 42;
}

Foo.prototype = {
method: function() {}
};

function Bar() {}

Bar.prototype = new Foo();
Bar.prototype.foo = 'Hello World';

Bar.prototype.constructor = Bar;

var test = new Bar();
  1. 我们处于 global-EC,初始化。

图片虽然很丑陋,好歹也是自己画的。有些地方不准确,有些地方有错误。不要在意这些细节(当然也省略了巨多的细节),内存中的对象大概就是这种模样。一般JS引擎都提供了__proto__供大家调试代码。而这形成了一个链条,人称原型链。干啥用的?继承。也就是复用代码。

  1. 现在来执行代码。
  • 那就是执行第5行,改变了Foo.prototype。 没名字那儿,我就用???代替了。
  • 再来执行第11行代码。这个new先不考虑,这里会调用特定的方法,当然这里也会产生新的EC,并在在里面生成一个新的对象,这个新对象{value: 42, __proto__: Foo.prototype}。当退出这个EC后,我们Bar.prototype之前的样子应该是{constructor: Bar, __proto__: Object.prototype},不过现在换人了;就像第5行那里一样,Foo.prototype的值也换人了。
  • 接着执行第12行代码。
  • 接着执行第14行代码。
  • 最后执行第16行代码。就像第11行,我们还是不考虑new,不考虑这个新的EC。现在test就不是undefined了。

此时,test.foo, test.value, test.constructor, test.method, test.hasOwnProperty通过原型链都可以使用了。

上篇文章abstract中,那时候我说 this 不重要。this是一个keyword,在new Foo()中的this和那时候的this用法完全不一样,这里的thisFunction.prototype.call, Function.prototype.apply中一样,都是特别提供的。

我们上面的图片,简化,只画出了global-EC,其他EC没画出来。不过可以看出来,如果我在其他EC中定义一个函数,返回此函数。然后我用一个变量接受,那么,虽然此时那个EC已经不存在,但是由于我用变量引用了此函数值,那么内存中还是存在这个函数对象,通过它的[[Scopes]],也能访问消失的EC中定义的名字(比如变量名字,函数名字)。很多时候我们用的

1
(function shit(shit){...}(window))

它运行产生一个EC,完了退出,但是我们如果在外环境引用了返回值(比如传window进去,把新属性挂在上面),那么虽然此EC已退出,但是其中涉及的对象还是存在于内存中。

abstract-of-JavaScript-???

一天不装逼,就难受。本来还想装一下,但是打开 ecma-262 自己就绝望了;没有猴年马月不可能看一遍。只好自己举栗子来说明一下JavaScript中的原型,作用域……

栗子(一)

example 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var ILoveU = 'are you kidding?';

function helloWorld(argc, argv){
"use strict";

var BBC = "2B";

function worldCup2018 () {
var no10 = "Messi";
debugger; //停在这里,我们随便看看;你用其他方法调试也可以。
return BBC;
}

worldCup2018();

return null;//不小心把这句删除了,后面截图注意这里,无大碍。
}

helloWorld(1, "holy shit!");

这里不会用什么奇技淫巧,注重基本概念的理解。我不会定义一个这个的函数 function shit(shit){var shit; return shit;}。这ecma-262发展太快了。不断有新的特性加入,还有概念上的改名。先有个简单的理解,以后再慢慢细化。

我们让栗子(一)跑起来,用Chrome 【版本 67.0.3396.99(正式版本) (64 位)】吧,我觉得灰常好用(我搞不懂,IE11在win7上跑,反正很难用,我也不想截图了)。

先粗略的过一遍,直观的感受一下。

  1. 我们第一个要看的就是 Call Stack

Call Stack 中,最底下的(anonymous)就是大伙说的 global Execution Context,我们的源代码就在这里面运行。其中定义一个变量,一个函数,然后到了 19行,调用了helloWorld,就产生了新的 helloWord-EC;里面定义了一个”2B”变量,一个函数,再到14行调用了worldCup2018,产生了worldCup2018-EC。

这种Stack数据结构哪里都有它的身影,什么push,pop……

瞅了一眼ecma-262,哎,真是复杂……你只要记住,调用函数就会产生一个新的数据结构EC就得了(至于第一个global-EC怎么产生的?还有没有其他方法产生?我们后面会有所涉及)。

爱因斯坦:「如果你无法向6岁小孩解释它,那代表你自己也不明白。」
对这句话,我是深表怀疑。老爱真的说过?鸡汤喝多了,不好。该下功夫的地方还是自己出力,我还想一个月让小孩长到20岁那么大呢。谈不上什么对错,看山是山,看山不是山,看山还是山,不多说了。

  1. 假设,我们让代码停在第一行(怎么停?踩刹车啊!自己去改改)。我有句话不知当讲不当讲?这个点,其实挺重要的。此时已经进入了global-EC。但是在进入之前,V8(或者其他引擎)会创建好 global object(到底怎么弄的?我也不知道,或许我说的就是错的,但是 global object 得有)。这是什么东东?
    简单说,global object上面挂了很多东西,比如 Infinity,NaN,parseInt,Number,Object,Map,Promise……。记住,是在执行代码之前创建的global object。管你有没有代码,都有这东西。浏览器执行你的代码,产生global-EC,上面说了这是一个重要的数据结构,要存很多值。情况没有我们想的那么简单,但是复杂的情况我们不考虑,呵呵(不管你我理解对错,你我的代码都能运行,或许还很完美。你没养过猪,但是会吃红烧肉啊!)。

3. fuck ecma-262。我们还是来说global-EC,我们只看Realm部分。
> Before it is evaluated, all ECMAScript code must be associated with a realm. Conceptually, a realm consists of a set of intrinsic objects, an ECMAScript global environment, all of the ECMAScript code that is loaded within the scope of that global environment, and other associated state and resources.
global object挂上去, global Environment Record也挂上去。
我他妈还以为自己在实现ecma-262呢!

  1. 看着我们的代码,我们还是来说global-EC,(我不知道EC这个数据结构各个部分该叫什么名字,网上有叫VariableObject/ActiveObject,ScopeChain,thisValue的)。我也不打算起什么名字了。放个图,看吧。

此时Scope里面就一个Global,Global上挂了global object,还有各种乱七八糟的属性;注意ILoveU: undefinedhelloWorld: f helloWorld(argc, argv)。此时我们的代码还在第一行。这也就是进入EC的时候,初始化阶段;然后才是执行代码。(明白这两个阶段,你就能明白什么时候一个名字绑定了你所期望的值。)

  • 初始化阶段,把var,FD都存入当前环境,也就是Scope的Global中。var的变量ILoveU,名字存进去,值是undefined。FD helloWorld名字也存进去,值就是一个函数对象。(FD、FE、NFE、FS自便查找)(注意:Scope,GLobal是当前我用的调试器中的。不必在意这些名字。只需记住有个数据结构存储环境即可。就是你一眼看过全局代码,有些名字需要存起来。)this被设置为 Global,此时就是window。

Scope,这个词,我不知道为什么很多地方都叫作用域。我还是觉得环境更准确。任何程序的运行,都必须有外界提供一个初始环境。硬件给操作系统提供,操作系统给各种游戏、浏览器提供,浏览器给JS代码提供。不管是外环境还是内环境,都是事物发展所必须的。你说个人名“王麻子”,你的小伙伴就知道你在说“隔壁老王”,而不是说公元前666年的老王;小伙伴们都默认了一个小环境;如果没有环境,什么都说不清。当然,如果你隔壁两边都住的“王麻子”,就需要提供更多的信息,才能区分你说的左隔壁还是右隔壁老王。

还有一点很重要,我们点击看到helloWorld,能看到[[Scopes]]。这个是干啥用的?先不管干啥用的,它的值,记录了定义时环境。helloWord哪里定义的,global-EC中啊,所以它的[[Scopes]]值就是global-EC的Scope,这里是含有一个元素的数组的形式,也就是[Global]。

  • 执行阶段,好的,那我就一步一步执行即可。第一行代码,执行完毕。ILoveU: "are you kidding?";然后就到了17行 helloWorld(1, "holy shit!"); ,那么我们继续执行。欧,我们进入helloWord-EC了。

我们不扯乱七八糟的名称了。直接撸代码。

  1. 那我们就来看看helloWord-EC
  • 初始化阶段,这个是函数调用产生的EC,比global-EC多了参数,但还是要构建环境。在局部环境Local里存argc: 1, argv: "holy shit!", BBC: undefined, worldCup2018: f worldCup2018(), this: undefined,实际应该还有arguments对象,不过Chrome浏览器显示的数据应该都是优化过的。(后面会稍稍提及。)helloWord产生了Local,再加helloWord的[[Scopes]]共同构成了此时的Scope。注意,我用了"use strict";,就是不想过多涉及this,我觉得 this is not important, at least for now, it’s irrelevant. 如果没有strict,this会被设置为window。 worldCup2018的[[Scopes]]就是helloWord-EC的Scope,也就是[Closure (helloWorld), Global]。

  • 执行阶段,走一步瞧瞧,BBC: "2B",我们又来到了14行worldCup2018();,没啥可说的,继续走起。

  1. 那我们就来看看worldCup2018-EC
  • 初始化阶段,初始化局部环境Local,外加它自己(worldCup2018)的[[Scopes]],构成此时的Scope。你或许很纳闷,Closure (helloWorld)里面只有一个BBC: "2B",其实这里应该是最少显示了,显示多余的没卵用。worldCup2018有一句return BBC,仅仅用到了Closure (helloWorld)中的BBC,如果用到了 helloWorld的argc,这里也会显示;如果连BBC也没有用到,Chrome这里就不会有Closure (helloWorld),直接优化掉了。因为此时,Closure (helloWorld)对worldCup2018来说就是多余的,但是挂在那里也是可以的。(比如你在worldCup2018里面再定义一个函数并且此函数用到了BBC,再调用一下此函数,那么Closure (helloWorld)对worldCup2018就不能优化掉。)

  • 执行阶段,没什么可说的。

我们该回去了。没必要再定义66层函数了。三层,我都感觉多了。我脑子不够用。

注意看 Call Stack。

Look,我们退出了worldCup2018-EC。时间不早了,继续走。

退出了helloWord-EC

退出了global-ECglobal-EC应该是程序关闭了才退出。调试器在这里插了一脚,这里应该与调试有关)。

回家吃饭吧。
本来打算几句话讲讲prototype,scope。到现在却感觉Call Stack,尤其EC都说的很乱。改天补充吧。

register

搞不懂为啥要用手机号注册?

我基本除了用了十几年的网易产品,支付宝之类的。其他几乎没用过。微信刚出来用了几天而已。至于百度的自从要绑手机,全扔了。看虎牙直播(除了看Dota,主要是有时候打飞机需要素材而已),又要绑手机,不绑不能发言,我完全都不发言了。还是github这些好,注册都不用手机号。

无奈

换个手机号,不小心把cnblogs账号,google账号,hotmail账号……全丢了。我也是草他大爷了。怎么都申请不回来。不明白,为啥要赋予手机这么多功能;打电话已经不重要,重要的是能发射原子弹。

古人诚不欺我

很多问题,萦绕脑海很多年。有好多话想说。说不出来。现代社会与古代社会有什么区别?仅仅生产力猛。兴,百姓苦;亡,百姓苦。智慧啥的,完全不是一个档次。

css-selector-thing

为什么CSS选择器是从右往左解析?,突然看到这个题目。只是觉得,有蹊跷。(有看过浏览器源代码的同学请指教)。下面自己理一理这个问题。

20180704.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="20180704.css">
<title>S</title>
</head>
<body>
<div class="one">
<article class="little">
<header>little</header>
<p class="time">下午</p>
<p>下雨</p>
</article>
<article id="more">
<header>not little</header>
<p class="time">晚上</p>
<p data-weather="rain">
<span></span>停了
</p>
</article>
</div>
</body>
</html>

20180704.css

1
2
3
4
5
6
7
8
@charset "utf-8";
p {text-decoration: underline;}
.one {border-top: 3px solid #123456;}
.one header {font-size: 32px;}
.little .time {color: cyan;}
.one [data-weather="rain"] span {color: brown;}
.one .two .three {font-size: 250in;}
.three .two .one {font-size: 250in;}

~测试用的代码,不用在意细节~

看图,我也不说啥了。

the Document tree

我们看一下 CSS2.1 2.3 The CSS 2.1 processing model 第4小条, Annotate

Annotate every element of the document tree by assigning a single value to every
property that is applicable to the target media type.

the annotated document tree

好了,就先到这里。(我们只考虑我们自己写的样式)问题是 怎么得到这 annotated tree

第一种办法

从dom中取一个节点,然后拿这个节点去cssRules匹配。举几个栗子。

  1. 拿到 html,啥也没干。(只考虑自己写的样式)
  2. 拿到 div(class="one"),正好有 .one {border-top: 3px solid #123456;},标记上去。
  3. 拿到 p(class="time"), 哎,有 p {text-decoration: underline;},标记上去;再往下看,有 .little .time {color: cyan;},查看一下它的先祖,有 .little存在,标记上去。
  4. ……

第二种办法

我们拿一个cssRule,去dom中匹配。试一试。

  1. 拿到 p {text-decoration: underline;},那好,dom中那么多 p,全给标记上。
  2. 拿到 .one [data-weather="rain"] span {color: brown;},找到,标记上。
  3. 拿到 .one .two .three {font-size: 250in;},没找到,对不起。

仔细看第一种方法,拿一个节点,去匹配所有cssRules。也就是说我拿所有的cssRules去测试一个节点,然后下一个节点……。这黄花菜都凉了。

我们看第二种方法。我们就有了从左开始还是从右开始匹配的问题。

  1. .one [data-weather="rain"] span {color: brown;}
  • ltr:找到 .one,ok;然后再找子孙 [data-weather="rain"],ok;然后再找子孙 span,ok。
  • rtl:找到 span,查看先祖条件.one [data-weather="rain"],没问题。
  1. .one .two .three {font-size: 250in;}
  • ltr:找到 .one,ok;然后再找 .two,不存在。
  • rtl:没有 .three,不存在。

找到,我们上面用了这个词。怎么找到?我们的栗子简化多了。一般都是遍历dom返回一组节点。比如找到了一组 span,然后用限制条件,把不合格的剔除出去。这个简单的栗子中,rtl显然比ltr要快,rtl第一步就找到嫌疑节点(不过看看 .three .two .one,ltr第一步就排除,rtl开始还以为找到了。但这仅仅是我们构造的一个不寻常规则。)。复杂的情况下,节点,cssRules数量很大。rtl会具有更大的优势。

我们回头再看.one [data-weather="rain"] span {color: brown;}.one .two .three {font-size: 250in;},为什么从右边开始?因为我本来就是要找 span.three,它们自身就处于右边(当然,还要进行过滤,满足前面的限制条件)。浏览器也是用从右向左这个策略。浏览器还提供了几个常用的API:document.querySelector,document.querySelectorAll。比如document.querySelector('.one [data-weather="rain"] span')我们就能轻易的找到 <span>雨</span>所代表的节点。

这也就是用一个selector,怎么找到匹配的节点。Sizzle 就是干这个事情的(没用过,没看过,听别人说的)。暂时,我觉得document.querySelector,document.querySelectorAll,document.getElement*,够用了。

var

有没有var有什么区别?

1
2
var1 = "var1111"; //make sure typeof var1 === "undefined"
var var2 = "var2222";
  1. 这是第一个区别

    所以,你可以 delete var1

  2. 第二个区别

  • var1 实际是 Host.var1 (浏览器中,HOST就是window;node中,HOST就是global)
  • var2 实际是 VE.var2,(And what is VE ? 一个数据结构,此时是window,我很可能错了。感觉自己在放屁,TBC。)

看看 Object

this,这里是 window。)

所以,你可以 delete Object;在window中你也看不到 Object;对不起,我骗了你,在 [default properties]确实有 Object;其实是当我 for (var p in window)时,p不到Object

再抄点东西吧

A var statement declares variables that are scoped to the running execution context’s VariableEnvironment.

sth-about-css-vp

something about css viewport

page 1

1.jpg

我还用尺子量了,宽度≈400mm,高度≈250mm;最佳分辨率1440*900;点距≈0.2778mm。然后,设置不同的分辨率,用GetDeviceCaps获得了令人费解的宽度以及高度,单位肯定不是mm了。不知道Windows操作系统搞得什么鬼?(显示器很老了,系统是XP,别打我)

page 2

2.jpg

使用 400mm×250mm,1400×900,我们可以计算出 91.44 Pixels Per Inch。但是Windows有一个 LOGPIXELSX=96,LOGPIXELSY=96,也就是96px/Inch,继续使用400mm×250mm,可以计算出屏幕为1512×945。

如果我们认定 400mm×250mm,那么

  1. 1Pixel = 1dd(dot distance)=0.2778mm,1400Pixel × 900 Pixel
  2. 1px = (1/96)Inch=0.2646mm,1512px × 945 px

page 3

3.jpg

假定 400mm×250mm,那么

  1. 1Pixel1 = 1dd(dot distance)=0.2778mm,1400 Pixel1 × 900 Pixel1
  2. 1Pixel2 = 0.3125mm,1280Pixel2 × 800 Pixel2
  3. 1px = (1/96)Inch=0.2646mm,1512px × 945 px
    单位真是乱的一比,能不带单位尽量不带了。真是不知道叫啥了,Pixel不提,我们直接给Pixel1,Pixel2长度值。起名字,确实是个难题。

page 4

4.jpg

一些网上弄到的数据。
x1 Pixel1 / y1 Pixel1 Per Inch = x2 Pixel2 / y2 Pixel2 Per Inch

page 5

5.jpg

我们自己再算几下
假定 1chuizi = 0.614mm,锤子嘛,我觉得锤子做单位就不错

  • 4.7”
    • 1Pixel4.7” = 0.078mm,1334 Pixel4.7” × 750 Pixel4.7”
    • 169chuizi × 95chuizi
  • 5.5”
    • 1Pixel5.5” = 0.0634mm,1920 Pixel5.5” × 1080 Pixel5.5”
    • 198chuizi × 112chuizi
  • 5”
    • 1Pixel5” = 0.0865mm,1280 Pixel5” × 720 Pixel5”
    • 180chuizi × 101chuizi

page 6

6.jpg

device-independent-pixel,系统给应用提供的单位,但是算一下,1dip4.7”、1dip5.5”、1dip5”并不是完全相等。dip实际值也是设备相关的。

  • iOS UIScreen获取
  • Android DisplayMetrics获取

相关联的参数还有不少,我们只要“宽”,“高”

page 7

7.jpg

如何确定合理的dip?
Android 1dip = (1/160)Inch = 0.15875mm, 也就是说 160PPI 的时候,1dip = 1Pixel160ppi(我这里Pixel都用长度值了,不说多少个像素)
直接用 1dip = (1/160)Inch 来计算,

  1. 1dip = 2Pixel320ppi
  2. 1dip = 1.84Pixel294ppi(RedMi3S)(好尴尬 1.84)
    所以,Android给PPI定了区间,294按照DENSITY_XHIGH(320)计算。density = 2(设备像素比)
    1dipRedMi3S = 2Pixel294ppi,也就是说 1dipRedMi3S = (1/147)Inch
  • 1280 Pixel294ppi × 720 Pixel294ppi
  • 697 dip × 392 dip
  • 640 dipRedMi3S × 360 dipRedMi3S

page 8

8.jpg

iOS的dip叫point。通过UIScreen,能获得 Wdip × Hdip,DPR(设备像素比)。
没事可以算算具体数值,但是6SP还搞事情了(假装2208 × 1242?)。

说白了,就是在同一个坐标系中,用不同的单位度量;你也可以认为是不同的坐标系,然后映射一下。

page 9

9.jpg

只是一个思路而已,这里说得也不是很清楚。当然也有错误,FF screen.width,Chrome screen.width获得的值,指的就是不同的对象。FF s.w指的是dip(随着缩放,dpr改变,而疯狂改变,当然dpr有上下限);Chrome s.w指的是Pixel,也就是分辨率中的w。
PC端缩放,dpr都会变。而手机端即使缩放,dpr固定不变。(并未验证所有浏览器。不过我自己手头的模型都是这样。不排除其他模型存在。)

page 10

10.jpg

viewport ☞ ICB ☞ canvas ☞ viewport
这就是我们渲染页面的大概过程。(细节我也不懂,也看不懂浏览器源代码,不知道怎么具体计算,用了什么MapMode……)
PC端viewport拉拉扯扯都变了,手机端独占屏幕(除去菜单部分)(反正我是拉不动)。
viewport除了看,主要还是为ICB提供初始值。PC端一般尺寸一样大。移动端如果没有 <meta viewport>,也没有@viewport,vendor会提供一个固定值。
我觉得initial viewport就是看的,actual viewport控制ICB的。

page 11

11.jpg

这里的测试,不严谨。结论也有待商榷。
不过可以看出来,我们从网页用JavaScript代码获得的单位是 dip
而且我们有viewport,有ICB,有canvas,渲染网页应该足够了。(layout viewport,visual viewport,ideal viewport 不知道干啥的?)
PC端IE对viewport的支持,也是测试头疼。

page 12

12.jpg

我手机测试的情况,我都无法理解。alert出来的d.d.cw,居然和document.write出来的不一样。
不过我还是坚持,VP不变,DPR不变,ICB由你通过(@viewport 或者 meta)设置。
至于1cm在代码里,在屏幕,在纸上……怎么映射,我也不知道。我想很多年前,你在css中写下1px的时候,它就表示显示器上的1Pixel吧。

page A

A.jpg

显示器(AOC E2270Sw),windows 7。网上复制代码测试,还是一头雾水。所以自己搞了一堆单位 mm,mm’,mm’’’,mm’’’’
当然 mm 人家是正统的宇宙级长度单位

page B

B.jpg

CSS 2.1DAM L1 抄袭而来。

page C

C.jpg

VUM L3具体怎么算,参考这里。

For print media and similar high-resolution devices, the anchor unit should be one of the standard physical units (inches, centimeters, etc). For lower-resolution devices, and devices with unusual viewing distances, it is recommended instead that the anchor unit be the pixel unit. For such devices it is recommended that the pixel unit refer to the whole number of device pixels that best approximates the reference pixel.

显示器(AOC E2270Sw),windows 7。 1dev_pixel = 0.2485mm,1ref_pixel = 0.26mm。 css 1px = 1dev_pixel ?

高ppi手机上难道 css 1px = (1/96)inch? 不,(注意用词should,recommended);根据我们前面几页应该是 1px ☞ 1dip,系统知道dip和Pixel,映射一下就好,然后有缩放就缩放到VP。

px is their canonical unit, css 1cm? 1cm=96px/25.4。所以都转化成px计算。

ps

PC要的是自适应,Mobile要的是适配(至多自适应一下Landscape/Portrait)。