smallwebbird

smallwebbird

Member Since 4 years ago

Experience Points
1
follower
Lessons Completed
1
follow
Lessons Completed
10
stars
Best Reply Awards
50
repos

69 contributions in the last year

Pinned
⚡ 一款用kotlin语言开发的记录旅行日记的app
⚡ 从零开始vue
⚡ A declarative, efficient, and flexible JavaScript library for building user interfaces.
⚡ 冴羽写博客的地方,预计写四个系列:JavaScript深入系列、JavaScript专题系列、ES6系列、React系列。
⚡ 🌈a beautify polyfill for native drag!
Activity
Oct
11
4 days ago
Activity icon
issue

smallwebbird issue smallwebbird/blogs

smallwebbird
smallwebbird

WebAssembly 基础

WebAssembly 基础 WebAssembly 介绍 官网介绍:WebAssembly 或者 wasm 是一个可移植、体积小、加载快并且兼容 Web 的全新格式。 分析一下WebAssembly 这个词由Web和Assembly组成,Web代表和前端有关,Assembly 汇编的意思,汇编对应着机器码,而机器码对应着指令集,那么什么是指令集呢?先来看一张图片

图片来自 WebAssembly入门-未来可能发生的巨变 参考上图,计算机的主要架构如上。最底层是 CPU 的指令集,主要分为复杂指令集和简单指令集。 复杂指令集是 x86、x64(也叫 x86-64, amd64) 两种架构,专利在 Intel 和 AMD 两家公司手里, 该架构 CPU 主要是 Intel 和 AMD 两家公司,这种 CPU 常用在 PC 机上,包括 Windows,macOS 和 Linux。 简单指令集是 arm 一种架构,专利在 ARM 公司手里,该架构 CPU 主要有高通、三星、苹果、华为海思、联发科等公司。这种 CPU 常用在手机上,包括安卓和苹果。 那么什么是指令集呢?直接把阮一峰的老师的一个 例子 粘过来,大家可以看一下。 c 语言的源程序。 int add_a_and_b(int a, int b) { return a + b; }

int main() { return add_a_and_b(2, 3); }

所对应的汇编就是下边的样子。 _add_a_and_b: push %ebx mov %eax, [%esp+8] mov %ebx, [%esp+12] add %eax, %ebx pop %ebx ret

_main: push 3 push 2 call _add_a_and_b add %esp, 8 ret

这里的 push 、mov 每一条指令就是指令集规定的内容,规定了操作码、操作数以及具体的功能。当然这里是用汇编表示的,主要是为了我们人类来读写,最终还会转成 0,1 序列。上边每个单词都会有一个数字相对应,比如 add 指令对应 00000011 。 通过规定的指令集(加法的指令,压栈指令等),编写相关程序,然后 CPU 就会一条一条的执行,最终实现相应的功能。 而 WebAssembly 就规定了一套指令集,更准确的来说是虚拟指令集,因为这套指令集是跑在虚拟机上的,而不是直接由硬件运行。(指令内容来源自WebAssembly入门-未来可能发生的巨变) 不支持在 Docs 外粘贴 block 简单来说就是,编译器将C++, Go,Rust 等编译为中间代码,再转化为WebAssembly 字节码(类似java的字节码),WebAssembly 字节码是一种抹平了不同 CPU 架构的机器码,WebAssembly 字节码不能直接在任何一种 CPU 架构上运行, 但由于非常接近机器码,可以非常快的被翻译为对应架构的机器码,因此 WebAssembly 运行速度和机器码接近。 WebAssembly.compile(new Uint8Array( 00 61 73 6d 01 00 00 00 01 0c 02 60 02 7f 7f 01 7f 60 01 7f 01 7f 03 03 02 00 01 07 10 02 03 61 64 64 00 00 06 73 71 75 61 72 65 00 01 0a 13 02 08 00 20 00 20 01 6a 0f 0b 08 00 20 00 20 00 6c 0f 0b.trim().split(/[\s\r\n]+/g).map(str => parseInt(str, 16)) )).then(module => { const instance = new WebAssembly.Instance(module) const { add, square } = instance.exports console.log('2 + 4 =', add(2, 4)) console.log('3^2 =', square(3)) console.log('(2 + 5)^2 =', square(add(2 + 5)))})

将上面代码拷贝到浏览器控制台就能看到结果。综上所述可以知道wasm其实是一种二进制字节码,和机器码比较类似,我们都知道汇编语言可以被转化为机器码,同样wasm也有类似的汇编语言,被称为S-表达式(mdn定义),可以使用工具wat2wasm 在S-表达式 和 wasm 字节码之间相互转换 WebAssembly 由来 由于前端业务场景越来越多,业务越来越复杂,导致在一些性能比较差的机器上表现不好。表现不好一方面确实是业务场景比较复杂,另一方面就是javascript 这门语言本身的缺陷。其一javascript是一门解释型语言,首先解释一下编译型和解释型编程语言的区别。 编译型: 将源代码经过编译器转为机器码,在执行 解释型:代码运行过程中,将源代码经过编译器生成中间代码,中间代码再通过虚拟器生成目标平台的机器码执行。 引用知乎上的一句话,编译型就是提前做好一桌子菜,再吃,而解释型就相当于吃火锅,一边吃,一边煮 所以说解释型编译语言会比编译型语言慢些。个人认为这个并不怎么影响性能。 其二javascript是一门动态语言编写程序时无需考虑变量类型,对于开发人员确实友好,但是对于js引擎来说并不友好。在js引擎没有引入JIT之前,假如一个方法被不同模块调用10次,那么这个方法也会被解释10次,显然这是很浪费性能。引入JIT后看一下v8引擎执行js的过程

Js 源代码经过词法分析、语法分析、语义分析生成AST树,再生成中间代码,中间代码进入解释器中执行,同时分析器会监控代码的执行情况,如果一段代码被反复执行,那么这个段代码被标记为热点代码,同时会把这段代码送到编译器中编译,同时生成优化后机器码,等下次执行到这段代码,就可以直接运行优化后的代码。但是也有特殊的情况,因为js是动态语言,类型是不固定的,有可能上一秒这个段代码被标记为热点代码,下一秒该热点代码对应的优化代码可能就被丢弃。感兴趣的可以看一下这篇文章 ASM.js 所以为了解决类型问题WebAssembly前身ASM.js出现,ASM.js 是 Mozilla 在 2013 年推出的,ASM.js是一个javascript严格子集,ASM.js 虽然可以手写,但是一般都是使用编译器将C++/C或者一些其他语言转为ASM.js文件。生成的ASM.js文件变量都是静态类型,不用在运行时判断变量类型,从而使得 js 引擎可以采用 AOT(Ahead Of Time) 的编译策略,也就是在运行前直接编译成机器码,因此运行速度会有一定的提升。那为什么ASM.js 并没有流行起来,其一它还是没有一个统一的标准。它只是一个由一个厂商推出的,非标准的 JavaScript 子集而已,而它的使用者根据自己的偏好和习惯来使用它。WebAssembly 则不同,它是由几大主要的浏览器厂商共同设计的。其二无论ASM.js如何优化,归根结底还是一个js文件,看一下上面v8引擎执行js的图片,可以看出只要是js文件,就需要经过解析,生成中间代码,而这两步是JavaScript代码在引擎执行过程当中消耗时间最多的两步。而WebAssembly不用经过这两步。这就是WebAssembly比asm.js更快的原因。

Emscripten介绍 Emscripten 是一个针对WebAssembly的开源编译器,它可以将C和C++代码或任何其他使用LLVM的语言编译成WebAssembly,并在Web、Node.js或其他wasm运行时运行它。 Emscripten 中包含俩个重要的工具链

  • emcc 是clang和gcc的临时替代品,emcc使用LLVM 和 clang将c/c++编译为WebAssembly
  • Emscripten SDK用于安装整个工具链,包括EMCC和LLVM等。Emscripten SDK(Emsdk)可以在Linux、Windows或MacOS上使用。 安装

Get the emsdk repo

git clone https://github.com/emscripten-core/emsdk.git

Enter that directory

cd emsdk

Fetch the latest version of the emsdk (not needed the first time you clone)

git pull

Download and install the latest SDK tools.

./emsdk install latest

Make the "latest" SDK "active" for the current user. (writes .emscripten file)

./emsdk activate latest

Activate PATH and other environment variables in the current terminal

source ./emsdk_env.sh

通过以上操作,在当前命令行运行emcc -v,打印如下代表安装成功 emcc -v

emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 2.0.29 (28ca7fb7ce895b21013212e4644a5794a15a76f9) clang version 14.0.0 (https://github.com/llvm/llvm-project 8e284be04f2cd43a821289133a759afa2844f935) Target: wasm32-unknown-emscripten Thread model: posix InstalledDir: /Users/bytedance/Desktop/emsdk/upstream/bin

为了确保每次打开终端都可以使用emcc,还需要将如下代码加入到.bash_profile或.zsh source emcc目录/emsdk_env.sh &> /dev/null

使用

  • 将c/c++编译为js // test.cpp #include

using namespace std;

int main() { cout << "Hello World" << endl; }

运行emcc ./test.cpp,同级目录生成a.out.js 和 a.out.wasm文件,第二个是包含编译代码的WebAssembly文件,第一个是包含加载和执行代码的运行时支持的JavaScript文件。然后可以使用nodejs运行js node ./a.out.js

终端输出Hello World

  • Emscripten还可以生成用于测试嵌入式JavaScript的HTML。要生成HTML,请使用-o(输出)命令并指定一个html文件作为目标文件: emcc test.cpp -o hello.html

然后可以在浏览器中打开hello.html 不幸的是,一些浏览器(包括Chrome、Safari和Internet Explorer)不支持file://xhr请求,并且不能加载HTML所需的额外文件(如.wasm文件或下面提到的打包文件数据)。对于这些浏览器,您需要使用本地Web服务器提供文件,然后打开http://localhost:8000/hello.html). 本人在练习的时候使用的是http-server 安装 npm i http-server -g

在工作目录运行

-o 打开浏览器

-p 指定端口

http-server ./ -o -p 8085

在浏览器中打开8085端口 WebAssembly 会取代 Javascript吗? 我认为不会。我认为WebAssembly 和 JavaScript 是相辅相成的,WebAssembly是被设计成JavaScript的一个完善、补充,而不是一个替代品。大家怎么认为? 参考链接 Emscripten 官网 c++项目转成wasm全过程 https://juejin.cn/post/6844903709806182413#heading-27 https://juejin.cn/post/6844903469808091143

Sep
12
1 month ago
Activity icon
issue

smallwebbird issue smallwebbird/blogs

smallwebbird
smallwebbird

短期学习路线

Vue 源码

React 源码

SSR 相关

React hooks

实现一门语言

Webassembly

Activity icon
issue

smallwebbird issue smallwebbird/blogs

smallwebbird
smallwebbird

react hooks

useSubscription

监听事件源的一个官方维护的hooks

使用

安装包

npm install use-subscription

关于useSubscription

useMutableSource

rfc 参考 参考

Aug
29
1 month ago
Activity icon
issue

smallwebbird issue smallwebbird/blogs

smallwebbird
smallwebbird

WebAssembly 之 Emscripten 安装(MacOS)

介绍

Emscripten 是一个针对WebAssembly的开源编译器,它可以将C和C++代码或任何其他使用LLVM的语言编译成WebAssembly,并在Web、Node.js或其他wasm运行时运行它。 Emscripten 中包含俩个重要的工具链

  • emcc 是clang和gcc的临时替代品,emcc使用LLVM 和 clang将c/c++编译为WebAssembly
  • Emscripten SDK用于安装整个工具链,包括EMCC和LLVM等。Emscripten SDK(Emsdk)可以在Linux、Windows或MacOS上使用。

安装

# Get the emsdk repo
git clone https://github.com/emscripten-core/emsdk.git

# Enter that directory
cd emsdk

# Fetch the latest version of the emsdk (not needed the first time you clone)
git pull

# Download and install the latest SDK tools.
./emsdk install latest

# Make the "latest" SDK "active" for the current user. (writes .emscripten file)
./emsdk activate latest

# Activate PATH and other environment variables in the current terminal
source ./emsdk_env.sh

通过以上操作,在当前命令行运行emcc -v,打印如下代表安装成功

emcc -v

emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 2.0.29 (28ca7fb7ce895b21013212e4644a5794a15a76f9)
clang version 14.0.0 (https://github.com/llvm/llvm-project 8e284be04f2cd43a821289133a759afa2844f935)
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /Users/bytedance/Desktop/emsdk/upstream/bin

为了确保每次打开终端都可以使用emcc,还需要将如下代码加入到.bash_profile.zsh

source emcc目录/emsdk_env.sh &> /dev/null

使用

  1. c/c++编译为js
// test.cpp
#include <iostream>

using namespace std;

int main()
{
    cout << "Hello World" << endl;
}

运行emcc ./test.cpp,同级目录生成a.out.jsa.out.wasm文件,第二个是包含编译代码的WebAssembly文件,第一个是包含加载和执行代码的运行时支持的JavaScript文件。然后可以使用nodejs运行js

node ./a.out.js

终端输出Hello World 2. Emscripten还可以生成用于测试嵌入式JavaScript的HTML。要生成HTML,请使用-o(输出)命令并指定一个html文件作为目标文件:

emcc test.cpp -o hello.html

然后可以在浏览器中打开hello.html 不幸的是,一些浏览器(包括Chrome、Safari和Internet Explorer)不支持file://xhr请求,并且不能加载HTML所需的额外文件(如.wasm文件或下面提到的打包文件数据)。对于这些浏览器,您需要使用本地Web服务器提供文件,然后打开http://localhost:8000/hello.html). 本人在练习的时候使用的是http-server 安装

npm i http-server -g

在工作目录运行

# -o 打开浏览器
# -p 指定端口
http-server ./ -o -p 8085 

在浏览器中打开8085端口 3. 访问本地文件

我们的C/C++代码可以使用普通的libc Stdio API(fopen、flose等)访问文件

JavaScript通常在Web浏览器的沙箱环境中运行,不能直接访问本地文件系统。 Emscripten模拟一个文件系统,您可以使用普通的libc Stdio API从编译后的C/C++代码访问该文件系统。 您要访问的文件应该预加载或嵌入到虚拟文件系统中。 预加载(或嵌入)生成对应于编译时相对于当前目录的文件系统结构的虚拟文件系统。 修改test.cpp的代码如下

// Copyright 2012 The Emscripten Authors.  All rights reserved.
// Emscripten is available under two separate licenses, the MIT license and the
// University of Illinois/NCSA Open Source License.  Both these licenses can be
// found in the LICENSE file.

#include <stdio.h>
int main()
{
    FILE *file = fopen("test.txt", "rb");
    if (!file)
    {
        printf("cannot open file\n");
        return 1;
    }
    while (!feof(file))
    {
        char c = fgetc(file);
        if (c != EOF)
        {
            putchar(c);
        }
    }
    fclose(file);
    return 0;
}

创建test.txt

hello test 

以下命令用于指定要在运行任何编译代码之前预加载到Emscripten的虚拟文件系统中的数据文件。这种方法很有用,因为浏览器只能从网络异步加载数据(Web Worker除外),而许多本机代码使用同步文件系统访问。预加载确保在编译代码有机会访问Emscripten文件系统之前完成数据文件的异步下载(并且文件可用)。

emcc test.cpp -o hello.html --preload-file test.txt

然后使用本地服务器运行生成的html文件

http-server ./ -o -p 8085 

浏览器终端输出 hello test

参考链接

Emscripten 官网

Aug
28
1 month ago
Aug
15
2 months ago
Activity icon
issue

smallwebbird issue smallwebbird/blogs

smallwebbird
smallwebbird

从头搭建一个GitLab CI/CD

从去年12月份到现在,迷迷糊糊过了大半年,感觉进入了自己舒适区,以前公司周末是大小周,小周的时候想,这个周末只放一天假,我要好好休息,大周末时候想,这个周末终于双休了,一定要好好休息,就这样浑浑噩噩的过了大半年,刚不久公司宣布双休了,同时我也对自己说: 不能再这样下去了,所以决定每周周内最少抽出8个小时学习,周末抽出8个小时学习。

Activity icon
created branch

smallwebbird in smallwebbird/blogs create branch gh-pages

createdAt 2 months ago
Activity icon
created repository
createdAt 2 months ago
Activity icon
issue

smallwebbird issue smallwebbird/blogs

smallwebbird
smallwebbird

pointer-events属性

这个属性就是,当我们希望一个元素不被点击但希望它的下层元素可以点击,我们就可以使用这个属性 例如一下代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .father{
            width: 100px;
            height: 100px;
            border: 1px solid red;
        }
        .son{
            width: 50px;
            height: 50px;
            background: red;
        }
        .son1{
            width: 70px;
            height: 70px;
            border: 1px solid Blue;
            position: absolute;
            left: 0;
            top: 0;
            pointer-events: none;
            z-index: 22;
        }
    </style>
</head>
<body>
    <div class="father">
        <div class="son"></div>
        <div class="son1"></div>
    </div>
    <script>
        var son = document.getElementsByClassName('son')[0];
        son.addEventListener('click', function(){
            console.log(111111111);
        }, false)
    </script>
</body>
</html>

但是在这里遇到一个问题,就是当父元素层级正常,使子元素的层级为-1,使它比父元素的层级低,然后在父元素中使用pointer-events:none;发现不能点击子元素,同样的情况发现在俩个兄弟元素中,当我把一个兄弟元素的层级设置为负数,然后另一个兄弟元素层级正常,然后在正常层级的元素上使用pointer-events:none;发现不能点击下面的层级为负数的兄弟元素

Activity icon
issue

smallwebbird issue smallwebbird/blogs

smallwebbird
smallwebbird

css中的calc属性

工作中遇到这个操作符,应用场景是父元素是自动适应屏幕宽度,父元素中有一个固定高度的子元素,还有一个自适应高度的子元素,然后这个自适应屏幕高度的子元素可以使用calc(100% - 固定高度的子元素的高度),应用这个css属性要注意,就是操作符俩边都应该有一个空格相隔

Activity icon
issue

smallwebbird issue smallwebbird/blogs

smallwebbird
smallwebbird

a标签设置样式的顺序

a;link 未访问链接的样式 a:visited 访问过链接的样式 a:hover 悬浮的样式 a:active 点击时的样式 有人总结为love/hate 爱恨原则

Activity icon
issue

smallwebbird issue smallwebbird/blogs

smallwebbird
smallwebbird

一些获取浏览器视口,body宽度的问题总结

我把所有这些相关的东西都放下面的一份代码中

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <ul>
        <li>11111111111111111111111</li>
        <li>11111111111111111111111</li>
        <li>11111111111111111111111</li>
        <li>11111111111111111111111</li>
        <li>11111111111111111111111</li>
        <li>11111111111111111111111</li>
        <li>11111111111111111111111</li>
        <li>11111111111111111111111</li>
        <li>11111111111111111111111</li><li>11111111111111111111111</li>
        <li>11111111111111111111111</li>
        <li>11111111111111111111111</li>
        <li>11111111111111111111111</li>
        <li>11111111111111111111111</li>
        <li>11111111111111111111111</li><li>11111111111111111111111</li>
        <li>11111111111111111111111</li>
        <li>11111111111111111111111</li>
        <li>11111111111111111111111</li><li>11111111111111111111111</li>
        <li>11111111111111111111111</li>
        <li>11111111111111111111111</li>
        <li>11111111111111111111111</li>
        <li>11111111111111111111111</li><li>11111111111111111111111</li>
        <li>11111111111111111111111</li>
        <li>11111111111111111111111</li>
        <li>11111111111111111111111</li>
        <li>11111111111111111111111</li>
        <li>11111111111111111111111</li>
        <li>11111111111111111111111</li>
        <li>11111111111111111111111</li><li>11111111111111111111111</li>
        <li>11111111111111111111111</li>
    </ul>
    <script>
        //火狐浏览器
        console.log('window.innerWidth:'+window.innerWidth) //视口的宽度
        console.log('window.outerWidth:'+window.outerWidth) //整个浏览器的宽度
        console.log('window.innerHeight:'+window.innerHeight) //视口的高度
        console.log('window.outerHeight:'+window.outerHeight)  //浏览器的高度
        console.log('body.clientWidth:'+document.body.clientWidth) //元素的宽度不包括border和margin,也不包括滚动条,
        console.log('body.clientHeight:'+document.body.clientHeight) //元素的高度不包括border和margin,也不包括垂直滚动条,
        console.log('body.offsetWidth:'+document.body.offsetWidth) //包括元素的padding,margin,border如果元素使用::after
        //和::before,不包括这部分,如果元素被设置display:none或者它的祖先被设置display:none那么它将返回0
        console.log('body.offsetHeight'+document.body.offsetHeight) //和上述一样
        console.log('body.scrollWidth:'+document.body.scrollWidth) //包括元素的内容宽度也包含溢出内容的宽度,包含padding不包含margin,border,
        //他也包括::before,::after,如果没有出现溢出他和clientWidth一致
        console.log('body.scrollHeight:'+document.body.scrollHeight) //和宽度一样
        console.log('body.scrollTop:'+document.body.scrollTop) //360,百度,safrai,搜狐浏览器都支持,但是IE,火狐和谷歌,opera都不支持
        console.log('body.scrollLeft:'+document.body.scrollLeft)
        console.log('documentElement.clientWidth:'+document.documentElement.clientWidth)
        //documentElement返回的是html,所以上面元素是返回html元素的client,也就是视口的,这个宽度比innerWidth小
        //因为他是html的宽度,但是innerWidth返回的浏览器视口的宽度
        console.log('documentElement.clientHeight:'+document.documentElement.clientHeight)
        console.log('documentElement.scrollTop:'+document.documentElement.scrollTop)
        console.log('documentElement.scrollLeft'+document.documentElement.scrollLeft)
        //这个属性支持谷歌,火狐,Ie和opera正好和上面的scrollTop支持的相反
        console.log('window.screen.height'+window.screen.height)
        console.log('window.screen.width'+window.screen.width)
        //高度和innerHeight的高度是相同的
        window.onscroll = function(){
            console.log(document.documentElement.scrollTop)
        }
        //
    </script>
</body>
</html>

又增加了一些内容

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .test{
            width: 100px;
            height: 100px;
            border: 1px solid red;
            background: red;
        }
    </style>
</head>
<body>
        <ul>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li><li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li><li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
                <li>111111111111111111111111111111111111111111</li>
        
            </ul>
    <div class="test">
        
    </div>
    <ul>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li><li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li><li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>
        <li>111111111111111111111111111111111111111111</li>

    </ul>
    <button id="btn">按钮</button>
    <script>
        let btn = document.getElementById('btn');
        btn.addEventListener('click', function(e){
            // document.elementFromPoint(50, 50).style.background = 'red'
            // let rect = document.getElementsByClassName('test')[0].getBoundingClientRect();
            // alert(rect.left+'-'+rect.right+'-'+rect.top+'-'+rect.bottom);
            // document.getElementsByClassName('test')[0].scrollIntoView(true);
            let left = document.getElementsByClassName('test')[0].clientLeft;
            let top = document.getElementsByClassName('test')[0].clientTop;
            alert('距离左边:'+left+'距离上边的距离:'+top);
        },false)
        document.getElementsByClassName('test')[0].addEventListener('click', function(e){
            console.log('点击点距离屏幕左边的距离screenX:'+e.screenX)
            console.log('点击点距离屏幕上边的距离screenY:'+e.screenY)
            console.log('点击点距离元素左边的距离clientX:'+e.clientX)  //和e.x相同
            console.log('点击点距离元素上边的距离clientY:'+ e.clientY)  //和e.y相同
            console.log('点击点距离document左边的距离pageX:'+e.pageX)
            console.log('点击点距离document上边的距离pageY:'+e.pageY)
        },false)
    </script>
</body>
</html>
Activity icon
issue

smallwebbird issue smallwebbird/blogs

smallwebbird
smallwebbird

css hover时改变其他状态

如果鼠标悬浮在父元素中,子元素的样式改变可以使用如下的css father:hover son{}父元素和子元素空格隔开 如果悬浮的元素是父元素,改变兄弟元素的样式,可以使用如下的css father:hover + son{} 看一下如下的例子

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .father{
            width: 100px;
            height: 100px;
            border: 1px solid red;
        }
        .son{
            width: 50px;
            height: 50px;
            border: 1px solid yellow;
        }
        .brother{
            width: 100px;
            height: 100px;
            border: 1px solid blue;
        }
        .father:hover .son{
            background: red;
        }
        .father:hover + .brother{
            background: red;
        }
    </style>
</head>
<body>
    <div class="father">
        <div class="son"></div>
    </div>
    <div class="brother">

    </div>
</body>
</html>
Activity icon
issue

smallwebbird issue smallwebbird/blogs

smallwebbird
smallwebbird

opacity:0; visiable:hidden;

opacity:0是透明度为0;也就是设置了透明度,但是元素的本身的效果是有的,比如说我给一个按钮设置透明度为0,它还是可以点击,而visiable:hidden;也是透明的,但是它是不可交互的

Activity icon
issue

smallwebbird issue smallwebbird/blogs

smallwebbird
smallwebbird

css伪类focus-within

根据mdn的描述,该伪类表示一个元素或者它的后代获得焦点的样式 先看这个例子,有如下代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .one{
            width: 500px;
            height: 500px;
            border: 1px solid black;
        }
        .two{
            width: 300px;
            height: 300px;
            border:1px solid black;
            margin: 0 auto;
            margin-top: 100px;
        }
        .three{
            width: 100px;
            height: 100px;
            border: 1px solid black;
            margin: 0 auto;
            margin-top: 100px;
            text-align: center;
            line-height: 100px;
        }
        .one:focus-within{
            background: red;
        }
        .two:focus-within{
            background: yellow;
        }
        .three:focus-within{
            background: blue;
        }
    </style>
</head>
<body>
    <div class="one">
        <div class="two">
            <div class="three">
                <button>按钮</button>
            </div>
        </div>
    </div>
</body>
</html>

honeycam 2018-12-27 13-05-45 点击按钮时能够触发背景颜色 把它用在表单上用来展示,当输入框被选中时整个表单被选中的状态 先来看代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .wrap{
            width: 300px;
            height: 150px;
            border: 1px solid gray;
            padding: 20px 20px;
        }
        .one{
            width: 250px;
            height: 50px;
            border: 1px solid gray;
            margin-top: 20px;
        }
        .wrap:focus-within{
            background: blue;
            opacity: 0.3;
        }
        .one:focus-within{
            border: 5px solid red;
        }
    </style>
</head>
<body>
    <form action="" class="wrap">
        <input type="text" class="one">
        <input type="text" class="one">
    </form>
</body>
</html>

honeycam 2018-12-27 13-27-03

Activity icon
issue

smallwebbird issue smallwebbird/blogs

smallwebbird
smallwebbird

关于line-height还有vertical-align

请看下面三个链接,看完之后,我相信大家对这俩个属性都有非常清晰的理解 张鑫旭 好文章 好文章 好文章 好文章

Previous