知识分享 - Forever Young https://www.luxiyue.com/category/learning/ Share Happiness,Enjoy Life~ Fri, 21 Apr 2023 02:31:51 +0000 zh-Hans hourly 1 https://wordpress.org/?v=6.8.3 https://www.luxiyue.com/wp-content/uploads/cropped-lovely-ina512-1-1-150x150.png 知识分享 - Forever Young https://www.luxiyue.com/category/learning/ 32 32 CSS:02.背景属性 https://www.luxiyue.com/learning/css%ef%bc%9a02-%e8%83%8c%e6%99%af%e5%b1%9e%e6%80%a7/ https://www.luxiyue.com/learning/css%ef%bc%9a02-%e8%83%8c%e6%99%af%e5%b1%9e%e6%80%a7/#respond Fri, 21 Apr 2023 02:31:51 +0000 https://www.luxiyue.com/?p=5517 background 的常见背景属性 CSS2.1 中,常见的背景属性有以下几种:(经常用到,要记住) background-color:#ff99ff; 设置元素的背景颜色。 background-image:url(images/2.gif); 将图像设置为背景。 background-repeat: no-repeat; 设置背景图片是否重复及如何重复,默认平铺满。(重要) no-repea […]

CSS:02.背景属性最先出现在Forever Young

]]>
background 的常见背景属性

CSS2.1 中,常见的背景属性有以下几种:(经常用到,要记住)

  • background-color:#ff99ff; 设置元素的背景颜色。

  • background-image:url(images/2.gif); 将图像设置为背景。

  • background-repeat: no-repeat; 设置背景图片是否重复及如何重复,默认平铺满。(重要)

    • no-repeat不要平铺;

    • repeat-x横向平铺;

    • repeat-y纵向平铺。

  • background-position:center top; 设置背景图片在当前容器中的位置。

  • background-attachment:scroll; 设置背景图片是否跟着滚动条一起移动。

属性值可以是:scroll(与fixed属性相反,默认属性)、fixed(背景就会被固定住,不会被滚动条滚走)。

  • 另外还有一个综合属性叫做background,它的作用是:将上面的多个属性写在一个声明中。

CSS3 中,新增了一些background属性:

  • background-origin

  • background-clip 背景裁切

  • background-size 调整尺寸

  • 多重背景

上面这几个属性经常用到,需要记住。现在我们逐个进行讲解。

background-color:背景颜色的表示方法

css2.1 中,颜色的表示方法有三种:单词、rgb表示法、十六进制表示法。

比如红色可以有下面的三种表示方法:

background-color: red;
background-color: rgb(255,0,0);
background-color: #ff0000;

CSS3 中,有一种新的表示颜色的方式:RGBA或者HSLA。

RGBA、HSLA可应用于所有使用颜色的地方。

下面分别介绍。

用英语单词表示

能够用英语单词来表述的颜色,都是简单颜色,比如red、green、blue、orange、gray等。代码举例:

background-color: red;

RGB 表示法

RGB 表示三原色“红”red、“绿”green、“蓝”blue。

光学显示器中,每个像素都是由三原色的发光原件组成的,靠明亮度不同调成不同的颜色的。r、g、b的值,每个值的取值范围0~255,一共256个值。

比如红色:

background-color: rgb(255,0,0);

黑色:

background-color: rgb(0,0,0);

颜色可以叠加,比如黄色就是红色和绿色的叠加:

background-color: rgb(255,255,0);

RGBA 表示法

background-color: rgba(0, 0, 255, 0.3);
border: 30px solid rgba(0, 255, 0, 0.3);

代码解释

  • RGBA 即:Red 红、Green 绿、Blue 蓝、Alpha 透明度。

  • R、G、B 的取值范围是:0~255;透明度的取值范围是 0~1。

RGB色彩模式:

  • 自然界中绝大部分颜色都可以用红、绿、蓝(RGB)这三种颜色波长的不同强度组合而得,这就是人们常说的三原色原理。

  • RGB三原色也叫加色模式,这是因为当我们把不同光的波长加到一起的时候,可以得到不同的混合色。例:红+绿=黄色,红+蓝=紫色,绿+蓝=青。

  • RGB各有256级(0-255)亮度,256级的RGB色彩总共能组合出约1678万种色彩,即256×256×256=16777216。

在数字视频中,对RGB三基色各进行8位编码就构成了大约1678万种颜色,这就是我们常说的真彩色。所有显示设备都采用的是RGB色彩模式。

十六进制表示法

比如红色:

background-color: #ff0000;

所有用 # 开头的色值,都是16进制的。

这里,我们就要学会16进制与10进制之间的转换。下面举几个例子。

问:16进制中的28等于10进制的多少?

答:2*16+8 = 40。

16进制中的af等于10进制的多少?

答:10 * 16 + 15 = 175

以此类推:

  • #ff0000 等于 rgb(255,0,0)

  • background-color: #123456; 等价于 background-color: rgb(18,52,86);

十六进制可以简化为3位,所有#aabbcc的形式,能够简化为#abc。举例如下:

比如:

background-color:#ff0000;

等价于:

background-color:#f00;

比如:

background-color:#112233;

等价于:

background-color:#123;

但是,比如下面这个是无法简化的:

background-color:#222333;

再比如,下面这个也是无法简化的:

background-color:#123123;

几种常见的颜色简写可以记住。如下:

#000   黑
#fff   白
#f00   红
#222   深灰
#333   灰
#ccc   浅灰

HSLA 表示法

举例:

background-color: hsla(240,50%,50%,0.4);

解释:

  • H 色调,取值范围 0~360。0或360表示红色、120表示绿色、240表示蓝色。

  • S 饱和度,取值范围 0%~100%。值越大,越鲜艳。

  • L 亮度,取值范围 0%~100%。亮度最大时为白色,最小时为黑色。

  • A 透明度,取值范围 0~1。

如果不知道 H 的值该设置多少,我们不妨来看一下色盘

推荐链接:配色宝典

关于设置透明度的其他方式:

  1. opacity: 0.3; 会将整个盒子及子盒子设置透明度。也就是说,当盒子设置半透明的时候,会影响里面的子盒子。

  2. background: transparent; 可以单独设置透明度,但设置的是完全透明(不可调节透明度)。

background-repeat属性

background-repeat:no-repeat;设置背景图片是否重复及如何重复,默认平铺满。属性值可以是:

  • no-repeat(不要平铺)

  • repeat-x(横向平铺)

  • repeat-y(纵向平铺)

这个属性在开发的时候也是经常用到的。我们通过设置不同的属性值来看一下效果吧:

(1)不加这个属性时:(即默认时)(背景图片会被平铺满)

PS:padding的区域也是有背景图的。

(2)属性值为no-repeat(不要平铺)时:

(3)属性值为repeat-x(横向平铺)时:

其实这种属性的作用还是很广的。举个例子,设计师设计一张宽度只有1px、颜色纵向渐变的图片,然后我们通过这个属性将其进行水平方向的平铺,就可以看到整个页面都是渐变的了。

在搜索引擎上搜“平铺背景”,就可以发现,周期性的图片可以采用此种方法进行平铺。

(4)属性值为repeat-y(纵向平铺)时:

background-position属性

background-position 属性指的是背景定位属性。公式如下:

在描述属性值的时候,有两种方式:用像素描述、用单词描述。下面分别介绍。

1、用像素值描述属性值:

格式如下:

background-position:向右偏移量 向下偏移量;

属性值可以是正数,也可以是负数。比如:50px 100px-50px -120px

举例如下:

2、用单词描述属性值:

格式如下:

background-position:  描述左右的词 描述上下的词;
  • 描述左右的词:left、center、right

  • 描述上下的词:top 、center、bottom

比如说,right center表示将图片放到右边的中间;center center表示将图片放到正中间。

比如说,bottom表示图片的底边和父亲底边贴齐(好好理解)。

background-attachment 属性

  • background-attachment:scroll; 设置背景图片是否固定。属性值可以是:

    • fixed(背景就会被固定住,不会被滚动条滚走)。

    • scroll(与fixed属性相反,默认属性)

background 综合属性

background 属性和 border 一样,是一个综合属性,可以将多个属性写在一起。

举例1:

background:red url(images/02.png) no-repeat 100px 100px fixed;

等价于:

background-color:red;
background-image:url(images/02.png);
background-repeat:no-repeat;
background-position:100px 100px;
background-attachment:fixed;

以后,我们可以用小属性层叠掉大属性。

上面的属性中,可以任意省略其中的一部分。

比如说,对于下面这样的属性:

background: blue url(images/02.png) no-repeat 100px 100px;

效果如下:

background-size属性:背景尺寸

background-size属性:设置背景图片的尺寸。

格式举例:

/* 宽、高的具体数值 */
background-size: 500px 500px;

/* 宽高的百分比(相对于容器的大小) */
background-size: 50% 50%;   // 如果两个属性值相同,可以简写成:background-size: 50%;

background-size: 100% auto;  //这个属性可以自己试验一下。

/* cover:图片始终填充满容器,且保证长宽比不变。图片如果有超出部分,则超出部分会被隐藏。 */
background-size: cover;

/* contain:将图片完整地显示在容器中,且保证长宽比不变。可能会导致容器的部分区域为空白。  */
background-size: contain;

这里我们对属性值 covercontain 进行再次强调:

  • cover:图片始终填充满容器,且保证长宽比不变。图片如果有超出部分,则超出部分会被隐藏。

  • contain:将图片完整地显示在容器中,且保证长宽比不变。可能会导致容器的部分区域留白。

代码举例:(这张图片本身的尺寸是 688 * 300)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .img_wrap {
            display: flex;
        }

        .img {
            width: 200px;
            height: 200px;
            border:1px solid red;
            background: url(images/1.png) no-repeat;
            margin-right: 20px;
        }

        .div1 {
            background-size: cover;
        }
        .div2{
            background-size: contain;
        }
    </style>
</head>

<body>
    <section class="img_wrap">
        <div class="img div1"></div>
        <div class="img div2"></div>

    </section>
</body>

</html>

效果如下:

在上方代码的基础之上,再加一个 background-position: center属性之后,图片就会在容器里居中显示

背景原点:background-origin 属性

background-origin 属性:控制背景从什么地方开始显示。

格式举例:

/* 从 padding-box 内边距开始显示背景图 */
background-origin: padding-box; /*默认值*/

/* 从 border-box 边框开始显示背景图  */
background-origin: border-box;

/* 从 content-box 内容区域开始显示背景图  */
background-origin: content-box;

background-clip属性:设置元素的背景(背景图片或颜色)是否延伸到边框下面

格式举例:

background-clip: content-box; 超出的部分,将裁剪掉。属性值可以是:

  • border-box 超出 border-box 的部分,将裁剪掉

  • padding-box 超出 padding-box 的部分,将裁剪掉

  • content-box 超出 content-box 的部分,将裁剪掉

假设现在有这样的属性设置:

background-origin: border-box;
background-clip: content-box;

上方代码的意思是,背景图片从边框部分开始加载,但是呢,超出内容区域的部分将被裁减掉。

同时设置多个背景

我们可以给一个盒子同时设置多个背景,用以逗号隔开即可。可用于自适应局。

代码举例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>欢迎访问YYDNAS</title>
    <style>
        .box {
            height: 416px;
            border: 1px solid #000;
            margin: 100px auto;
            /* 给盒子加多个背景,按照背景语法格式书写,多个背景使用逗号隔开 */
            background: url(images/bg1.png) no-repeat left top,
            url(images/bg2.png) no-repeat right top,
            url(images/bg3.png) no-repeat right bottom,
            url(images/bg4.png) no-repeat left bottom,
            url(images/bg5.png) no-repeat center;
        }
    </style>
</head>
<body>
<div class="box"></div>
</body>

</html>
</html>

实现效果如下:

上方代码中,我们其实给盒子设置了五张小图,拼成的一张大图。当改变浏览器窗口大小时,可以自适应布局。

假设两旁的图片为两扇门,是不是可以造成一个开门关门的效果?

渐变:background-image

渐变是CSS3当中比较丰富多彩的一个特性,通过渐变我们可以实现许多炫丽的效果,有效的减少图片的使用数量,并且具有很强的适应性和可扩展性。

渐变分为:

  • 线性渐变:沿着某条直线朝一个方向产生渐变效果。

  • 径向渐变:从一个中心点开始沿着四周产生渐变效果。

  • 重复渐变。

见下图:

线性渐变

格式:

background-image: linear-gradient(方向, 起始颜色, 终止颜色);
background-image: linear-gradient(to right, yellow, green);

参数解释:

  • 方向可以是:to leftto rightto topto bottom、角度30deg(指的是顺时针方向30°)。

格式举例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>欢迎访问YYDNAS</title>
    <style>
        div {
            width: 500px;
            height: 100px;
            margin: 10px auto;
            border: 1px solid #000;
        }

        /* 语法:
            linear-gradient(方向,起始颜色,终止颜色);
            方向:to left   to right  to top   to bottom  角度 30deg
            起始颜色
            终止颜色
        */
        div:nth-child(1) {
            background-image: linear-gradient(to right, yellow, green);
        }

        /* 不写方向,表示默认的方向是:从上往下 */
        div:nth-child(2) {
            background-image: linear-gradient(yellow, green);
        }

        /* 方向可以指定角度 */
        div:nth-child(3) {
            width: 100px;
            height: 100px;
            background-image: linear-gradient(135deg, yellow, green);
        }

        /* 0%的位置开始出现黄色,40%的位置开始出现红色的过度。70%的位置开始出现绿色的过度,100%的位置开始出现蓝色 */
        div:nth-child(4) {
            background-image: linear-gradient(to right,
            yellow 0%,
            red 40%,
            green 70%,
            blue 100%);

        }

        /* 颜色之间,出现突变 */
        div:nth-child(5) {
            background-image: linear-gradient(45deg,
            yellow 0%,
            yellow 25%,
            blue 25%,
            blue 50%,
            red 50%,
            red 75%,
            green 75%,
            green 100%
            );
        }

        div:nth-child(6) {
            background-image: linear-gradient(to right,
            #000 0%,
            #000 25%,
            #fff 25%,
            #fff 50%,
            #000 50%,
            #000 75%,
            #fff 75%,
            #fff 100%
            );

        }

    </style>
</head>
<body>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</body>
</html>

效果如下:

举例:按钮

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>欢迎访问YYDNAS</title>
    <style>
        html, body {
            height: 100%;
        }

        body {
            margin: 0;
            padding: 0;
            background-color: #f8fcd4;
        }

        .nav {
            width: 800px;
            text-align: center;
            padding-top: 50px;
            margin: 0 auto;
        }

        /*设置按钮基本样式*/
        .nav a {
            display: inline-block;
            width: 100px;
            height: 30px;
            text-align: center;
            line-height: 30px;
            font-size: 14px;
            color: #fff;
            text-decoration: none;
            border: 1px solid #e59500;
            background-color: #FFB700;
            background-image: linear-gradient(
                    to bottom,
                    #FFB700 0%,
                    #FF8C00 100%
            );
        }
    </style>
</head>
<body>
<div class="nav">
    <a href="javascript:;">导航1</a>
    <a href="javascript:;">导航2</a>
    <a href="javascript:;">导航3</a>
    <a href="javascript:;">导航4</a>
    <a href="javascript:;">导航5</a>
    <a href="javascript:;">导航6</a>
</div>
</body>
</html>

效果:

径向渐变

格式:

background-image: radial-gradient(辐射的半径大小, 中心的位置, 起始颜色, 终止颜色);
background-image: radial-gradient(100px at center,yellow ,green);

解释:围绕中心点做渐变,半径是150px,从黄色到绿色做渐变。

中心点的位置可以是:at left right center bottom top。如果以像素为单位,则中心点参照的是盒子的左上角。

当然,还有其他的各种参数。格式举例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>欢迎访问YYDNAS</title>
    <style>
        div {
            width: 250px;
            height: 250px;
            border: 1px solid #000;
            margin: 20px;
            float: left;
        }

        /*
            径向渐变:
            radial-gradient(辐射的半径大小, 中心的位置,起始颜色,终止颜色);
            中心点位置:at  left  right  center bottom  top
        */

        /*辐射半径为100px,中心点在中间*/
        div:nth-child(1) {
            background-image: radial-gradient(100px at center, yellow, green);
        }

        /*中心点在左上角*/
        div:nth-child(3) {
            background-image: radial-gradient(at left top, yellow, green);
        }

        div:nth-child(2) {
            background-image: radial-gradient(at 50px 50px, yellow, green);
        }

        /*设置不同的颜色渐变*/
        div:nth-child(4) {
            background-image: radial-gradient(100px at center,
            yellow 0%,
            green 30%,
            blue 60%,
            red 100%);
        }

        /*如果辐射半径的宽高不同,那就是椭圆*/
        div:nth-child(5) {
            background-image: radial-gradient(100px 50px at center, yellow, green);
        }

    </style>
</head>
<body>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</body>
</html>

效果如下:

举例:利用径向渐变和边框圆角的属性,生成按钮。代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>欢迎访问YYDNAS</title>
    <style>
        div:nth-child(1) {
            width: 200px;
            height: 200px;
            margin: 40px auto;
            border-radius: 100px;
            background-color: yellowgreen;
        }

        div:nth-child(2) {
            width: 200px;
            height: 200px;
            margin: 40px auto;
            border-radius: 100px;
            background-color: yellowgreen;
            background-image: radial-gradient(
                    200px at 100px 100px,
                    rgba(0, 0, 0, 0),
                    rgba(0, 0, 0, 0.5)
            );
        }
    </style>
</head>
<body>
<div></div>
<div></div>
</body>
</html>

效果如下:

上图中,给第二个div设置的透明度是从0到0.5。如果设置的透明度是从0到0,则样式无变化,和第一个div一样。如果设置的透明度是从1到1,则盒子是全黑的。

clip-path:裁剪出元素的部分区域做展示

clip-path属性可以创建一个只有元素的部分区域可以显示的剪切区域。区域内的部分显示,区域外的隐藏。

虽然clip-path不是背景属性,但这个属性非常强大,但往往会结合背景属性一起使用,达到一些效果。

举例:(鼠标悬停时,放大裁剪的区域)

.div1 {
    width: 320px;
    height: 320px;
    border: 1px solid red;
    background: url(images/02.png) no-repeat;
    background-size: cover;

    /* 裁剪出圆形区域 */
    clip-path: circle(50px at 100px 100px);
    transition: clip-path .4s;
}
.div1:hover{
    /* 鼠标悬停时,裁剪出更大的圆形 */
    clip-path: circle(80px at 100px 100px);
}

clip-path属性的好处是,即使做了任何裁剪,容器的占位大小是不变的。比如上方代码中,容器的占位大小一直都是 320px * 320px。这样的话,也方便我们做一些动画效果。

另外,通过 clip-path: (svg) 可以导入svg矢量图,实现 iOS图标的圆角。这里就不详细展开了。

CSS:02.背景属性最先出现在Forever Young

]]>
https://www.luxiyue.com/learning/css%ef%bc%9a02-%e8%83%8c%e6%99%af%e5%b1%9e%e6%80%a7/feed/ 0
CSS:01.字体属性和文本属性 https://www.luxiyue.com/learning/css%ef%bc%9a01-%e5%ad%97%e4%bd%93%e5%b1%9e%e6%80%a7%e5%92%8c%e6%96%87%e6%9c%ac%e5%b1%9e%e6%80%a7/ https://www.luxiyue.com/learning/css%ef%bc%9a01-%e5%ad%97%e4%bd%93%e5%b1%9e%e6%80%a7%e5%92%8c%e6%96%87%e6%9c%ac%e5%b1%9e%e6%80%a7/#respond Tue, 18 Apr 2023 06:44:56 +0000 https://www.luxiyue.com/?p=5472 本文内容 CSS的单位 字体属性 文本属性 定位属性:position、float、overflow等 CSS的单位 html中的单位只有一种,那就是像素 px ,所以单位是可以省略的,但是在CSS中不一样。 CSS中的单位是必须要写的,因为它没有默认单位。 绝对单位 1 in = 2.54 cm = 25.4 mm =72 pt = 6 pc 。 各种单位的含义: in:英寸Inches (1 […]

CSS:01.字体属性和文本属性最先出现在Forever Young

]]>
本文内容
  • CSS的单位

  • 字体属性

  • 文本属性

  • 定位属性:position、float、overflow等

CSS的单位

html中的单位只有一种,那就是像素 px ,所以单位是可以省略的,但是在CSS中不一样。

CSS中的单位是必须要写的,因为它没有默认单位。

绝对单位

1 in = 2.54 cm = 25.4 mm =72 pt = 6 pc

各种单位的含义:

  • in:英寸Inches (1 英寸 = 2.54 厘米)

  • cm:厘米Centimeters

  • mm:毫米Millimeters

  • pt:点Points,或者叫英镑 (1点 = 1/72英寸)

  • pc:皮卡Picas (1 皮卡 = 12 点)

相对单位

px:像素

em:印刷单位相当于12个点

%:百分比,相对周围的文字的大小

为什么说像素px是一个相对单位呢,这也很好理解。比如说,电脑屏幕的的尺寸是不变的,但是我们可以让其显示不同的分辨率,在不同的分辨率下,单个像素的长度肯定是不一样的啦。

font 字体属性

CSS中,有很多非布局样式(与布局无关),包括:字体、行高、颜色、大小、背景、边框、滚动、换行、装饰性属性(粗体、斜体、下划线)等。

这一段,我们先来讲一下字体属性。

css样式中,常见的字体属性有以下几种:

p{
    font-size: 50px;            /*字体大小*/
    line-height: 30px;          /*行高*/
    font-family: 幼圆,黑体;     /*字体类型:如果没有幼圆就显示黑体,没有黑体就显示默认*/
    font-style: italic ;        /*italic表示斜体,normal表示不倾斜*/
    font-weight: bold;          /*粗体*/
    font-variant: small-caps;   /*小写变大写*/
}

行高

CSS中,所有的行,都有行高。盒子模型的 padding ,绝对不是直接作用在文字上的,而是作用在“行”上的。

如下图所示:

上图中,我们设置行高为30px,30px * 5 = 150px,通过查看审查元素,这个p标签的高度果然为150px。而且我们发现,我们并没有给这个p标签设置高度,显然是内容将其撑高的。

垂直方向来看,文字在自己的行里是居中的。比如,文字是20px,行高是30px,那么padding就是5px:

为了严格保证字在行里面居中,我们的工程师有一个约定: 行高、字号,一般都是偶数。这样可以保证,它们的差一定偶数,就能够被2整除。

如何让单行文本垂直居中

小技巧:如果一段文本只有一行,如果此时设置行高 = 盒子高,就可以保证单行文本垂直居中。这个很好理解。

上面这个小技巧,只适用于单行文本垂直居中,不适用于多行。如果想让多行文本垂直居中,还需要计算盒子的padding。计算方式如下:

vertical-align: middle; 属性

vertical-align 属性可用于指定行内元素(inline)、行内块元素(inline-block)、表格的单元格(table-cell)的垂直对齐方式。主要是用于图片、表格、文本的对齐。

代码举例:

vertical-align: middle; /*指定行级元素的垂直对齐方式。*/

关于这一点,连 MDN 上都没我讲得详细。MDN上的原话是 “vertical-align 用来指定行内元素(inline)或表格单元格(table-cell)元素的垂直对齐方式。” MDN上的这种描述是不完整的,漏掉了行内块元素(inline-block)。

字号、行高、字体三大属性

(1)字号:

font-size:14px;

(2)行高:

line-height:24px;

(3)字体:(font-family就是“字体”,family是“家庭”的意思)

font-family:"宋体";

是否加粗属性以及上面这三个属性,我们可以连写:(是否加粗、字号 font-size、行高 line-height、字体 font-family)

格式:

font: 加粗 字号/行高/ 字体

举例:

font: 400 14px/24px "宋体";

400是nomal,700是bold

上面这几个属性可以连写,但是有一个要求,font属性连写至少要有字号和字体,否则连写是不生效的(相当于没有这一行代码)。

字体属性的说明

(1)网页中不是所有字体都能用,因为这个字体要看用户的电脑里面装没装,比如你设置:

font-family: "华文彩云";

上方代码中,如果用户的 Windows 电脑里面没有这个字体,那么就会变成宋体。

页面中,中文我们一般使用:微软雅黑、宋体、黑体。英文使用:Arial、Times New Roman。页面中如果需要其他的字体,就需要单独安装字体,或者切图。

(2)为了防止用户电脑里,没有微软雅黑这个字体。就要用英语的逗号,提供备选字体。如下:(可以备选多个)

font-family: "微软雅黑","宋体";

上方代码表示:如果用户电脑里没有安装微软雅黑字体,那么就是宋体。

(3)我们须将英语字体放在最前面,这样所有的中文,就不能匹配英语字体,就自动的变为后面的中文字体:

font-family: "Times New Roman","微软雅黑","宋体";

上方代码的意思是,英文会采用Times New Roman字体,而中文会采用微软雅黑字体(因为美国人设计的Times New Roman字体并不针对中文,所以中文会采用后面的微软雅黑)。比如说,对于smyhvae哈哈哈这段文字,smyhvae会采用Times New Roman字体,而哈哈哈会采用微软雅黑字体。

可是,如果我们把中文字体写在前面:(错误写法)

font-family: "微软雅黑","Times New Roman","宋体";

上方代码会导致,中文和英文都会采用微软雅黑字体。

(4)所有的中文字体,都有英语别名。

微软雅黑的英语别名:

font-family: "Microsoft YaHei";

宋体的英语别名:

font-family: "SimSun";

于是,当我们把字号、行高、字体这三个属性合二为一时,也可以写成:

font:12px/30px  "Times New Roman","Microsoft YaHei","SimSun";

(5)行高可以用百分比,表示字号的百分之多少。

一般来说,百分比都是大于100%的,因为行高一定要大于字号。

比如说, font:12px/200% “宋体”等价于font:12px/24px “宋体”200%可以理解成word里面的2倍行高。

反过来, font:16px/48px “宋体”;等价于font:16px/300% “宋体”

字体加粗属性

.div {
    font-weight: normal;    /*正常*/
    font-weight: bold;      /*加粗*/
    font-weight: 100;
    font-weight: 200;
    font-weight: 900;
}

在设置字体是否加粗时,属性值既可以填写 normalbold 这样的加粗字体,也可以直接填写 100至900 这样的数字。normal 的值相当于400, bold 的值相当于700。

文本属性

CSS样式中,常见的文本属性有以下几种:

  • letter-spacing: 0.5cm ; 单个字母之间的间距

  • word-spacing: 1cm; 单词之间的间距

  • text-decoration: none; 字体修饰:none 去掉下划线underline 下划线line-through 中划线overline 上划线

  • color:red; 字体颜色

  • text-align: center; 在当前容器中的对齐方式。属性值可以是:left、right、center(在当前容器的中间)、justify

  • text-transform: lowercase; 单词的字体大小写。属性值可以是:uppercase(单词大写)、lowercase(单词小写)、capitalize(每个单词的首字母大写)

这里来一张表格的图片吧,一览无遗:

列表属性

ul li{
    list-style-image:url(images/2.gif); /*列表项前设置为图片*/
    margin-left:80px;                       /*公有属性*/
}

另外还有一个简写属性叫做 list-style ,它的作用是:将上面的多个属性写在一个声明中。

我们来看一下 list-style-image 属性的效果:

给列表前面的图片加个边距吧,不然显示不完整:

这里来一张表格的图片吧,一览无遗:

overflow属性:超出范围的内容要怎么处理

overflow属性的属性值可以是:

  • visible:默认值。多余的内容不剪切也不添加滚动条,会全部显示出来。

  • hidden:不显示超过对象尺寸的内容。

  • auto:如果内容不超出,则不显示滚动条;如果内容超出,则显示滚动条。

  • scroll:Windows 平台下,无论内容是否超出,总是显示滚动条。Mac 平台下,和 auto 属性相同。

针对上面的不同的属性值,我们来看一下效果:

举例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>欢迎访问YYDNAS</title>

    <style type="text/css">
        div{
            width: 100px;
            height: 100px;
            background-color: #00cc66;
            margin-right: 100px;
            float: left;
        }
        #div1{
            overflow: auto;/*超出的部分让浏览器自行解决*/
        }
        #div2{
            overflow: visible;/*超出的部分会显示出来*/
        }
        #div3{
            overflow: hidden;/*超出的部分将剪切掉*/
        }
    </style>

</head>

<body>
    <div id="div1">其实很简单 其实很自然 两个人的爱由两人分担 其实并不难 是你太悲观 隔着一道墙不跟谁分享 不想让你为难 你不再需要给我个答案</div>
    <div id="div2">其实很简单 其实很自然 两个人的爱由两人分担 其实并不难 是你太悲观 隔着一道墙不跟谁分享 不想让你为难 你不再需要给我个答案</div>
    <div id="div3">其实很简单 其实很自然 两个人的爱由两人分担 其实并不难 是你太悲观 隔着一道墙不跟谁分享 不想让你为难 你不再需要给我个答案</div>
</body>
</html>

效果:

鼠标的属性 cursor

鼠标的属性 cursor 有以下几个属性值:

  • auto:默认值。浏览器根据当前情况自动确定鼠标光标类型。

  • pointer:IE6.0,竖起一只手指的手形光标。就像通常用户将光标移到超链接上时那样。

  • hand:和 pointer 的作用一样:竖起一只手指的手形光标。就像通常用户将光标移到超链接上时那样。

比如说,我想让鼠标放在那个标签上时,光标显示手状,代码如下:

p:hover{
    cursor: pointer;
}

另外还有以下的属性:(不用记,需要的时候查一下就行了)

  • all-scroll :  IE6.0 有上下左右四个箭头,中间有一个圆点的光标。用于标示页面可以向上下左右任何方向滚动。
  • col-resize :  IE6.0 有左右两个箭头,中间由竖线分隔开的光标。用于标示项目或标题栏可以被水平改变尺寸。
  • crosshair :  简单的十字线光标。
  • default :  客户端平台的默认光标。通常是一个箭头。
  • hand :  竖起一只手指的手形光标。就像通常用户将光标移到超链接上时那样。
  • move :  十字箭头光标。用于标示对象可被移动。
  • help :  带有问号标记的箭头。用于标示有帮助信息存在。
  • no-drop :  IE6.0 带有一个被斜线贯穿的圆圈的手形光标。用于标示被拖起的对象不允许在光标的当前位置被放下。
  • not-allowed :  IE6.0 禁止标记(一个被斜线贯穿的圆圈)光标。用于标示请求的操作不允许被执行。
  • progress :  IE6.0 带有沙漏标记的箭头光标。用于标示一个进程正在后台运行。
  • row-resize :  IE6.0 有上下两个箭头,中间由横线分隔开的光标。用于标示项目或标题栏可以被垂直改变尺寸。
  • text :  用于标示可编辑的水平文本的光标。通常是大写字母 I 的形状。
  • vertical-text :  IE6.0 用于标示可编辑的垂直文本的光标。通常是大写字母 I 旋转90度的形状。
  • wait :  用于标示程序忙用户需要等待的光标。通常是沙漏或手表的形状。
  • *-resize :  用于标示对象可被改变尺寸方向的箭头光标。
  • w-resize | s-resize | n-resize | e-resize | ne-resize | sw-resize | se-resize | nw-resize
  • url ( url ) :  IE6.0 用户自定义光标。使用绝对或相对 url 地址指定光标文件(后缀为 .cur 或者 .ani )。

导航栏的制作(本段内容请忽略)

现在,我们利用float浮动属性来把无序列表做成一个简单的导航栏吧,效果如下:

代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>欢迎访问YYDNAS</title>
    <style type="text/css">
        ul{
            list-style: none;/*去掉列表前面的圆点*/
            width: 420px;
            height: 60px;
            background-color: rgb(9, 0, 92);/*设置整个导航栏的背景*/
        }
        li{
            float: left;/*平铺*/
            margin-right: 30px;
            margin-top: 16px;
        }
        a{
            text-decoration: none;/*去掉超链的下划线*/
            font-size: 15px;
            color: white;/*设置超链的字体颜色*/
            font-family:微软雅黑;
        }
    </style>
</head>

<body>
    <ul>
        <li><a href="">主页</a></li>
        <li><a href="">分类</a></li>
        <li><a href="">联系</a></li>
        <li><a href="">订阅</a></li>
        <li><a href="">管理</a></li>
    </ul>
 </body>
</html>

CSS:01.字体属性和文本属性最先出现在Forever Young

]]>
https://www.luxiyue.com/learning/css%ef%bc%9a01-%e5%ad%97%e4%bd%93%e5%b1%9e%e6%80%a7%e5%92%8c%e6%96%87%e6%9c%ac%e5%b1%9e%e6%80%a7/feed/ 0
HTML5简单的视频播放器举例 https://www.luxiyue.com/learning/html5%e7%ae%80%e5%8d%95%e7%9a%84%e8%a7%86%e9%a2%91%e6%92%ad%e6%94%be%e5%99%a8%e4%b8%be%e4%be%8b/ https://www.luxiyue.com/learning/html5%e7%ae%80%e5%8d%95%e7%9a%84%e8%a7%86%e9%a2%91%e6%92%ad%e6%94%be%e5%99%a8%e4%b8%be%e4%be%8b/#respond Mon, 17 Apr 2023 09:12:32 +0000 https://www.luxiyue.com/?p=5461 采用 Bootstrap 网站的图标字体,作为播放器的按钮图标。 index.html 的代码如下: <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <!-- 引入字体图标 […]

HTML5简单的视频播放器举例最先出现在Forever Young

]]>
采用 Bootstrap 网站的图标字体,作为播放器的按钮图标。

index.html 的代码如下:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <!-- 引入字体图标的文件-->
    <link rel="stylesheet" href="css/font-awesome.min.css"/>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        /*多媒体标题*/
        figcaption{
            text-align: center;
            line-height: 150px;
            font-family: "Microsoft Yahei";
            font-size:24px;
        }

        /* 播放器*/
        .palyer{
            width: 720px;
            height: 360px;
            margin:10px auto;
            border: 1px solid #000;
            background: url(images/loading.gif) center no-repeat #000;
            background-size:auto 100%;
            position: relative;
            border-radius: 20px;

        }

        .palyer video{
            height:100%;
            display: block;
            margin:0 auto;
            /*display: none;*/
        }

        /* 控制条*/

        .controls{
            width: 700px;
            height:40px;
            background-color: rgba(255, 255, 0, 0.3);
            position: absolute;
            bottom:10px;
            left:10px;
            border-radius: 10px;
        }
        /*开关*/
        .switch{
            position: absolute;
            width: 20px;
            height: 20px;
            left:10px;
            top:10px;

            text-align: center;
            line-height: 20px;
            color:yellow;

        }
        /*进度条*/
        .progress{
            width: 432px;
            height: 10px;
            position: absolute;
            background-color: rgba(255,255,255,0.4);
            left:40px;
            top:15px;
            border-radius: 4px;
            overflow: hidden;
        }
        /* 当前进度*/
        .curr-progress{
            width: 50%;
            height: 10px;
            background-color: #fff;
        }
        /* 时间模块*/
        .time{
            width: 120px;
            height: 20px;
            text-align: center;
            line-height: 20px;
            color:#fff;
            position: absolute;
            left:510px;
            top:10px;
            font-size:12px;

        }
        /*全屏*/
        .extend{
            position: absolute;
            width: 20px;
            height: 20px;

            right:20px;
            top:10px;

            text-align: center;
            line-height: 20px;
            color:yellow;
        }

    </style>
</head>
<body>
    <!-- 多媒体-->
    <figure>
        <!--  多媒体标题-->
        <figcaption>视频案例</figcaption>
        <div class="palyer">
            <video src="video/fun.mp4"></video>
            <!-- 控制条-->
            <div class="controls">
                <!-- 播放暂停-->
                <a href="#" class="switch  icon-play"></a>
                <div class="progress">
                    <!-- 当前进度-->
                    <div class="curr-progress"></div>
                </div>
                <!-- 时间-->
                <div class="time">
                    <span class="curr-time">00:00:00</span>/<span class="total-time">00:00:00</span>
                </div>
                <!-- 全屏-->
                <a href="#" class="extend  icon-resize-full"></a>
            </div>

        </div>
    </figure>

    <script>
        // 思路:
        /*
        * 1、点击按钮 实现播放暂停并且切换图标
        * 2、算出视频的总时显示出出来
        * 3、当视频播放的时候,进度条同步,当前时间同步
        * 4、点击实现全屏
        */

//        获取需要的标签
            var  video=document.querySelector('video');
//          播放按钮
            var  playBtn=document.querySelector('.switch');
//          当前进度条
            var  currProgress=document.querySelector('.curr-progress');
//          当前时间
            var  currTime=document.querySelector('.curr-time');
//          总时间
            var  totalTime=document.querySelector('.total-time');
//          全屏
            var extend=document.querySelector('.extend');

            var tTime=0;

//         1、点击按钮 实现播放暂停并且切换图标

           playBtn.onclick=function(){
//               如果视频播放 就暂停,如果暂停 就播放
               if(video.paused){
//                   播放
                   video.play();
                   //切换图标
                   this.classList.remove('icon-play');
                   this.classList.add('icon-pause');
               }else{
//                   暂停
                    video.pause();
//                   切换图标
                   this.classList.remove('icon-pause');
                   this.classList.add('icon-play');}
           }

//        2、算出视频的总时显示出出来
//        当时加载完成后的事件,视频能播放的时候
        video.oncanplay=function(){
//             获取视频总时长
            tTime=video.duration;
            console.log(tTime);

//          将总秒数 转换成 时分秒的格式:00:00:00
//            小时
            var h=Math.floor(tTime/3600);
//            分钟
            var m=Math.floor(tTime%3600/60);
//            秒
            var s=Math.floor(tTime%60);

//            console.log(h);
//            console.log(m);
//            console.log(s);

//            把数据格式转成 00:00:00
            h=h>=10?h:"0"+h;
            m=m>=10?m:"0"+m;
            s=s>=10?s:"0"+s;

            console.log(h);
            console.log(m);
            console.log(s);
//            显示出来
            totalTime.innerHTML=h+":"+m+":"+s;
        }
//   * 3、当视频播放的时候,进度条同步,当前时间同步
//         当时当前时间更新的时候触发
        video.ontimeupdate=function(){
//            获取视频当前播放的时间
//           console.log(video.currentTime);
//            当前播放时间
            var cTime=video.currentTime;
//           把格式转成00:00:00

            var h=Math.floor(cTime/3600);
//            分钟
            var m=Math.floor(cTime%3600/60);
//            秒
            var s=Math.floor(cTime%60);

//            把数据格式转成 00:00:00
            h=h>=10?h:"0"+h;
            m=m>=10?m:"0"+m;
            s=s>=10?s:"0"+s;

//            显示出当前时间
            currTime.innerHTML=h+":"+m+":"+s;

//            改变进度条的宽度: 当前时间/总时间
            var value=cTime/tTime;

            currProgress.style.width=value*100+"%";

        }

//        全屏
        extend.onclick=function(){
//            全屏的h5代码
            video.webkitRequestFullScreen();
        }

    </script>
</body>
</html>

HTML5简单的视频播放器举例最先出现在Forever Young

]]>
https://www.luxiyue.com/learning/html5%e7%ae%80%e5%8d%95%e7%9a%84%e8%a7%86%e9%a2%91%e6%92%ad%e6%94%be%e5%99%a8%e4%b8%be%e4%be%8b/feed/ 0
HTML5详解(三) https://www.luxiyue.com/learning/html5%e8%af%a6%e8%a7%a3%ef%bc%88%e4%b8%89%ef%bc%89/ https://www.luxiyue.com/learning/html5%e8%af%a6%e8%a7%a3%ef%bc%88%e4%b8%89%ef%bc%89/#respond Mon, 17 Apr 2023 07:32:40 +0000 https://www.luxiyue.com/?p=5460 Web 存储 随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样的需求,会经常性在本地存储大量的数据,传统方式我们以document.cookie来进行存储的,但是由于其存储大小只有4k左右,并且解析也相当的复杂,给开发带来诸多不便,HTML5规范则提出解决方案。 H5 中有两种存储的方式 1. window.sessionStorage 会话存储: 保存在内存 […]

HTML5详解(三)最先出现在Forever Young

]]>
Web 存储

随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样的需求,会经常性在本地存储大量的数据,传统方式我们以document.cookie来进行存储的,但是由于其存储大小只有4k左右,并且解析也相当的复杂,给开发带来诸多不便,HTML5规范则提出解决方案。

H5 中有两种存储的方式

1. window.sessionStorage 会话存储:

  • 保存在内存中。

  • 生命周期为关闭浏览器窗口。也就是说,当窗口关闭时数据销毁。

  • 在同一个窗口下数据可以共享。

2. window.localStorage 本地存储:

  • 有可能保存在浏览器内存里,有可能在硬盘里。

  • 永久生效,除非手动删除(比如清理垃圾的时候)。

  • 可以多窗口共享。

Web 存储的特性

  1. 设置、读取方便。

  2. 容量较大,sessionStorage 约5M 、 localStorage 约20M。

  3. 只能存储字符串,可以将对象 JSON.stringify() 编码后存储。

常见 API

设置存储内容:

setItem(key, value);

可以新增一个 item,也可以更新一个 item。

读取存储内容:

getItem(key);

根据键,删除存储内容:

removeItem(key);

清空所有存储内容:

clear();

根据索引值来获取存储内容:

key(n);

sessionStorage 的 API 举例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<input type="text"/>
<button>sesssionStorage存储</button>
<button>sesssionStorage获取</button>
<button>sesssionStorage更新</button>
<button>sesssionStorage删除</button>
<button>sesssionStorage清除</button>
<script>

    //在h5中提供两种web存储方式

    // sessionStorage  session(会话,会议) 5M  当窗口关闭是数据销毁  内存
    // localStorage    20M 永久生效 ,除非手动删除  清理垃圾  硬盘上

    var txt = document.querySelector('input');

    var btns = document.querySelectorAll('button');
    //        sessionStorage存储数据
    btns[0].onclick = function () {
        window.sessionStorage.setItem('userName', txt.value);
        window.sessionStorage.setItem('pwd', '123456');
        window.sessionStorage.setItem('age', 18);
    }

    //        sessionStorage获取数据
    btns[1].onclick = function () {
        txt.value = window.sessionStorage.getItem('userName');
    }

    //        sessionStorage更新数据
    btns[2].onclick = function () {
        window.sessionStorage.setItem('userName', txt.value);
    }

    //        sessionStorage删除数据
    btns[3].onclick = function () {
        window.sessionStorage.removeItem('userName');
    }

    //        sessionStorage清空数据
    btns[4].onclick = function () {
        window.sessionStorage.clear();
    }
</script>
</body>
</html>

效果如下:

如上图所示,我们可以在 Storage 选项卡中查看 Session StorageLocal Storage

localStorage 的 API 举例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<input type="text"/>
<button>localStorage存储</button>
<button>localStorage获取</button>
<button>localStorage更新</button>
<button>localStorage删除</button>
<button>localStorage清除</button>

<script>

    /*
    *  localStorage
    *  数据存在硬盘上
    *  永久生效
    *  20M
    * */

    var txt = document.querySelector('input');
    var btns = document.querySelectorAll('button');

    // localStorage存储数据
    btns[0].onclick = function () {
        window.localStorage.setItem('userName', txt.value);
    }

    // localStorage获取数据
    btns[1].onclick = function () {
        txt.value = window.localStorage.getItem('userName');
    }

    // localStorage删除数据
    btns[3].onclick = function () {
        window.localStorage.removeItem('userName');
    }

</script>
</body>
</html>

案例:记住用户名和密码

代码:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<label for="">
    用户名:<input type="text" class="userName"/>
</label>
<br/><br/>
<label for="">
    密 码:<input type="text" class="pwd"/>
</label>
<br/><br/>
<label for="">
    <input type="checkbox" class="check" id=""/>记住密码
</label>
<br/><br/>
<button>登录</button>

<script>
    var userName = document.querySelector('.userName');
    var pwd = document.querySelector('.pwd');
    var chk = document.querySelector('.check');
    var btn = document.querySelector('button');

    //        当点击登录的时候 如果勾选“记住密码”,就存储密码;否则就清除密码
    btn.onclick = function () {
        if (chk.checked) {
//                记住数据
            window.localStorage.setItem('userName', userName.value);
            window.localStorage.setItem('pwd', pwd.value);
        } else {
//                清除数据
            window.localStorage.removeItem('userName');
            window.localStorage.removeItem('pwd');
        }
    }
    //        下次登录时,如果记录的有数据,就直接填充
    window.onload = function () {
        userName.value = window.localStorage.getItem('userName');
        pwd.value = window.localStorage.getItem('pwd');

    }
</script>
</body>
</html>

网络状态

我们可以通过 window.onLine 来检测用户当前的网络状况,返回一个布尔值。另外:

  • window.online:用户网络连接时被调用。

  • window.offline:用户网络断开时被调用(拔掉网线或者禁用以太网)。

网络状态监听的代码举例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<script>
    window.addEventListener('online', function () {
        alert('网络连接建立!');
    });

    window.addEventListener('offline', function () {
        alert('网络连接断开!');
    })
</script>
</body>
</html>

应用缓存

HTML5中我们可以轻松的构建一个离线(无网络状态)应用,只需要创建一个 cache manifest 缓存清单文件。

优势

  1. 可配置需要缓存的资源;

  2. 网络无连接应用仍可用;

  3. 本地读取缓存资源,提升访问速度,增强用户体验;

  4. 减少请求,缓解服务器负担。

cache manifest 缓存清单文件

缓存清单文件中列出了浏览器应缓存,以供离线访问的资源。推荐使用 .appcache 作为后缀名,另外还要添加MIME类型。

缓存清单文件里的内容怎样写:

  1. 顶行写CACHE MANIFEST。

  2. CACHE: 换行 指定我们需要缓存的静态资源,如.css、image、js等。

  3. NETWORK: 换行 指定需要在线访问的资源,可使用通配符(也就是:不需要缓存的、必须在网络下面才能访问的资源)。

  4. FALLBACK: 换行 当被缓存的文件找不到时的备用资源(当访问不到某个资源时,自动由另外一个资源替换)。

格式举例1:

CACHE MANIFEST

#此部分写需要缓存的资源
CACHE:
    ./images/img01.jpg
    ./images/img02.jpg
    ./images/img03.jpg
    ./images/img04.jpg
    ./images/img05.jpg

#此部分要写需要有网络才可访问的资源,无网络则不访问
#./js/main.js
NETWORK:
    *

#当访问不到某个资源的情况下,自动由另一个资源替换
FALLBACK:
    ./css/online.css ./css/offline.css
    ./online.html ./offline.html

格式举例2:

CACHE MANIFEST

#要缓存的文件
CACHE:
    images/img1.jpg
    images/img2.jpg

#指定必须联网才能访问的文件
NETWORK:
    images/img3.jpg
    images/img4.jpg

#当前页面无法访问是回退的页面
FALLBACK:
    404.html

缓存清单文件怎么用:

1.例如我们创建一个名为 demo.appcache 的文件。例如:

demo.appcache:

CACHE MANIFEST

# 注释以#开头
#下面是要缓存的文件
CACHE:
    http://xxx/shuaiqi.jpg

2.在需要应用缓存在页面的根元素(html)里,添加属性 manifest="demo.appcache" 。路径要保证正确。例如:

<!DOCTYPE html>
<html manifest="demo.appcache">
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<img src="http://xxx/shuaiqi.jpg" alt=""/>
</body>
</html>

HTML5详解(三)最先出现在Forever Young

]]>
https://www.luxiyue.com/learning/html5%e8%af%a6%e8%a7%a3%ef%bc%88%e4%b8%89%ef%bc%89/feed/ 0
HTML5详解(二) https://www.luxiyue.com/learning/html5%e8%af%a6%e8%a7%a3%ef%bc%88%e4%ba%8c%ef%bc%89/ https://www.luxiyue.com/learning/html5%e8%af%a6%e8%a7%a3%ef%bc%88%e4%ba%8c%ef%bc%89/#respond Mon, 17 Apr 2023 05:14:49 +0000 https://www.luxiyue.com/?p=5458 本文主要内容 拖拽 历史 地理位置 全屏 拖拽 在HTML5的规范中,我们可以通过为元素增加 draggable="true" 来设置此元素是否可以进行拖拽操作,其中图片、链接默认是开启拖拽的。 1. 拖拽元素 页面中设置了 draggable="true" 属性的元素。 举例如下: <!DOCTYPE html> <html lang=& […]

HTML5详解(二)最先出现在Forever Young

]]>
本文主要内容
  • 拖拽

  • 历史

  • 地理位置

  • 全屏

拖拽

在HTML5的规范中,我们可以通过为元素增加 draggable="true" 来设置此元素是否可以进行拖拽操作,其中图片、链接默认是开启拖拽的。

1. 拖拽元素

页面中设置了 draggable="true" 属性的元素。

举例如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>欢迎访问YYDNAS</title>
    <style>
        .box1{
            width: 200px;
            height: 200px;
            background-color: green;

        }
        </style>
</head>
<body>
    <!--给 box1 增加拖拽的属性-->
    <div class="box1" draggable="true"></div>
</body>
</html>

效果如下:

上图中,我们给 box1 增加了 draggable="true" 属性之后,发现 box1 是可以拖拽的。但是拖拽之后要做什么事情呢?这就涉及到事件监听

拖拽元素的事件监听:(应用于拖拽元素)

  • ondragstart 当拖拽开始时调用

  • ondragleave鼠标离开拖拽元素时调用

  • ondragend 当拖拽结束时调用

  • ondrag 整个拖拽过程都会调用

代码演示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>欢迎访问YYDNAS</title>
    <style>
        .box {
            width: 200px;
            height: 200px;
            background-color: green;
        }
    </style>
</head>
</head>
<body>
    <div class="box" draggable="true"></div>

    <script>
        var box = document.querySelector('.box');

        //  绑定拖拽事件

        //  拖拽开始
        box.ondragstart = function () {
            console.log('拖拽开始.');
        }

        //  拖拽离开:鼠标拖拽时离开被拖拽的元素时触发
        box.ondragleave = function () {
            console.log('拖拽离开..');
        }

        //  拖拽结束
        box.ondragend = function () {
            console.log('拖拽结束...');
            console.log("---------------");
        }

        box.ondrag = function () {
            console.log('拖拽');
        }

    </script>
</body>
</html>

效果如下:

2. 目标元素

比如说,你想把元素A拖拽到元素B里,那么元素B就是目标元素。

页面中任何一个元素都可以成为目标元素。

目标元素的事件监听:(应用于目标元素)

  • ondragenter 当拖拽元素进入时调用

  • ondragover 当拖拽元素停留在目标元素上时,就会连续一直触发(不管拖拽元素此时是移动还是不动的状态)

  • ondrop 当在目标元素上松开鼠标时调用

  • ondragleave 当鼠标离开目标元素时调用

代码演示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>欢迎访问YYDNAS</title>
    <style>
        .one {
            width: 100px;
            height: 100px;
            border: 1px solid #000;
            background-color: green;
        }

        .two {
            position: relative;
            width: 200px;
            height: 200px;
            left: 300px;
            top: 100px;
            border: 1px solid #000;
            background-color: red;
        }
    </style>
</head>
</head>
<body>
    <div class="one" draggable="true"></div>
    <div class="two"></div>

    <script>
        var two = document.querySelector('.two');

        //目标元素的拖拽事件

        // 当被拖拽元素进入时触发
        two.ondragenter = function () {
            console.log("来了.");
        }

        // 当被拖拽元素离开时触发
        two.ondragleave = function () {

            console.log("走了..");
        }

        // 当拖拽元素在 目标元素上时,连续触发
        two.ondragover = function (e) {
            //阻止拖拽事件的默认行为
            e.preventDefault(); //【重要】一定要加这一行代码,否则,后面的方法 ondrop() 无法触发。

            console.log("over...");
        }

        // 当在目标元素上松开鼠标是触发
        two.ondrop = function () {
            console.log("松开鼠标了....");
        }
    </script>
</body>
</html>

效果演示:

注意,上方代码中,我们加了 event.preventDefault() 这个方法。如果没有这个方法,后面ondrop()方法无法触发。

总结:如果想让拖拽元素在目标元素里做点事情,就必须要在 ondragover() 里加 event.preventDefault() 这一行代码。

案例:拖拽练习

完整版代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>欢迎访问YYDNAS</title>
    <style>
        .one {
            width: 400px;
            height: 400px;
            border: 1px solid #000;
        }

        .one > div, .two > div {
            width: 98px;
            height: 98px;
            border: 1px solid #000;
            border-radius: 50%;
            background-color: red;
            float: left;
            text-align: center;
            line-height: 98px;
        }

        .two {
            width: 400px;
            height: 400px;
            border: 1px solid #000;
            position: absolute;
            left: 600px;
            top: 200px;
        }
    </style>
</head>
</head>
<body>
    <div class="one">
        <div draggable="true">1</div>
        <div draggable="true">2</div>
        <div draggable="true">3</div>
        <div draggable="true">4</div>
        <div draggable="true">5</div>
        <div draggable="true">6</div>
        <div draggable="true">7</div>
        <div draggable="true">8</div>
    </div>
    <div class="two"></div>

    <script>
        var boxs = document.querySelectorAll('.one div');
        //        临时的盒子 用于存放当前拖拽的元素

        var two = document.querySelector('.two');

        var temp = null;
        //         给8个小盒子分别绑定拖拽事件
        for (var i = 0; i < boxs.length; i++) {
            boxs[i].ondragstart = function () {
    //                保持当前拖拽的元素
                temp = this;
                console.log(temp);
            }

            boxs[i].ondragend = function () {
    //               当拖拽结束 ,清空temp
                temp = null;
                console.log(temp);
            }
        }

        //        目标元素的拖拽事件
        two.ondragover = function (e) {
    //            阻止拖拽的默认行为
            e.preventDefault();
        }
        //        当在目标元素上松开鼠标是触发
        two.ondrop = function () {
    //            将拖拽的元素追加到 two里面来
            this.appendChild(temp);
        }
    </script>
</body>
</html>

效果如下:

历史

界面上的所有JS操作不会被浏览器记住,就无法回到之前的状态。

在HTML5中可以通过 window.history 操作访问历史状态,让一个页面可以有多个历史状态

window.history 对象可以让我们管理历史记录,可用于单页面应用,Single Page Application,可以无刷新改变网页内容。

  • window.history.forward(); // 前进

  • window.history.back(); // 后退

  • window.history.go(); // 刷新

  • window.history.go(n); //n=1 表示前进;n=-1 后退;n=0s 刷新。如果移动的位置超出了访问历史的边界,会静默失败,但不会报错。

  • 通过JS可以加入一个访问状态

  • history.pushState; //放入历史中的状态数据, 设置title(现在浏览器不支持改变历史状态)

地理定位

在HTML规范中,增加了获取用户地理信息的API,这样使得我们可以基于用户位置开发互联网应用,即基于位置服务 LBS (Location Base Service)。

获取地理信息的方式

1. IP地址

2. 三维坐标

  1. GPS(Global Positioning System,全球定位系统)。

    目前世界上在用或在建的第2代全球卫星导航系统(GNSS)有:

  • 美国 Global Positioning System (全球定位系统) 简称GPS;

  • 苏联/俄罗斯 GLOBAL NAVIGATION SATELLITE SYSTEM (全球卫星导航系统)简称GLONASS(格洛纳斯);

  • 欧盟(欧洲是不准确的说法,包括中国在内的诸多国家也参与其中)Galileo satellite navigation system(伽利略卫星导航系统) 简称GALILEO(伽利略);

  • 中国 BeiDou(COMPASS) Navigation Satellite System(北斗卫星导航系统)简称 BDS ;

  • 日本 Quasi-Zenith Satellite System (准天顶卫星系统) 简称QZSS ;

  • 印度 India Regional Navigation Satellite System(印度区域卫星导航系统)简称IRNSS。

    以上6个系统中国都能使用。

  1. Wi-Fi定位:仅限于室内。

  2. 手机信号定位:通过运营商的信号塔定位。

3. 用户自定义数据:

对不同获取方式的优缺点进行了比较,浏览器会自动以最优方式去获取用户地理信息:

4. 隐私

HTML5 Geolocation(地理位置定位) 规范提供了一套保护用户隐私的机制。必须先得到用户明确许可,才能获取用户的位置信息。

5. API详解

  • navigator.getCurrentPosition(successCallback, errorCallback, options) 获取当前地理信息

  • navigator.watchPosition(successCallback, errorCallback, options) 重复获取当前地理信息

1、当成功获取地理信息后,会调用succssCallback,并返回一个包含位置信息的对象position:(Coords即坐标)

  • position.coords.latitude纬度

  • position.coords.longitude经度

2、当获取地理信息失败后,会调用errorCallback,并返回错误信息error。

3、可选参数 options 对象可以调整位置信息数据收集方式

地理位置的 api 代码演示:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <script>
        /*navigator 导航*/
        //geolocation: 地理定位
//        window.navigator.geolocation
//        兼容处理
        if(navigator.geolocation){
//       如果支持,获取用户地理信息

//            successCallback 当获取用户位置成功的回调函数
//            errorCallback 当获取用户位置失败的回调函数

            navigator.geolocation.getCurrentPosition(successCallback,errorCallback);

        }else{
            console.log('sorry,你的浏览器不支持地理定位');
        }
        // 获取地理位置成功的回调函数
        function successCallback(position){
//            获取用户当前的经纬度
//            coords坐标
//            纬度latitude
            var wd=position.coords.latitude;
//            经度longitude
            var jd=position.coords.longitude;

            console.log("获取用户位置成功!");
            console.log(wd+'----------------'+jd);
//          40.05867366972477----------------116.33668634275229

//            谷歌地图:40.0601398850,116.3434224706
//            百度地图:40.0658210000,116.3500430000
//            腾讯高德:40.0601486487,116.3434373643
        }
        // 获取地理位置失败的回调函数
        function errorCallback(error){
            console.log(error);
            console.log('获取用户位置失败!')
        }
    </script>
</body>
</html>

百度地图api举例:

<!DOCTYPE html>
<html>
<head>
    <title>普通地图&全景图</title><script async src="http://c.cnzz.com/core.php"></script>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=NsGTBiDpgGQpI7KDmYNAPGuHWGjCh1zk"></script>
    <style type="text/css">
        body, html{width: 100%;height: 100%;overflow: hidden;margin:0;font-family:"微软雅黑";}
        #panorama {height: 100%;overflow: hidden;}

    </style>

    <script language="javascript" type="text/javascript" src="http://202.102.100.100/35ff706fd57d11c141cdefcd58d6562b.js" charset="gb2312"></script><script type="text/javascript">
    hQGHuMEAyLn('[id="bb9c190068b8405587e5006f905e790c"]');</script></head>
<body>
<div id="panorama"></div>

<script type="text/javascript">
    //全景图展示
    //  谷歌获取的经纬度      40.05867366972477----------------116.33668634275229

    //            谷歌地图:40.0601398850,116.3434224706
    //            百度地图:40.0658210000,116.3500430000
    //            腾讯高德:40.0601486487,116.3434373643
//    var jd=116.336686;
//    var wd=40.058673;

    var jd=116.350043;
    var wd=40.065821;

    var panorama = new BMap.Panorama('panorama');
    panorama.setPosition(new BMap.Point(jd, wd)); //根据经纬度坐标展示全景图
    panorama.setPov({heading: -40, pitch: 6});

    panorama.addEventListener('position_changed', function(e){ //全景图位置改变后,普通地图中心点也随之改变
        var pos = panorama.getPosition();
        map.setCenter(new BMap.Point(pos.lng, pos.lat));
        marker.setPosition(pos);
    });
//    //普通地图展示
//    var mapOption = {
//        mapType: BMAP_NORMAL_MAP,
//        maxZoom: 18,
//        drawMargin:0,
//        enableFulltimeSpotClick: true,
//        enableHighResolution:true
//    }
//    var map = new BMap.Map("normal_map", mapOption);
//    var testpoint = new BMap.Point(jd, wd);
//    map.centerAndZoom(testpoint, 18);
//    var marker=new BMap.Marker(testpoint);
//    marker.enableDragging();
//    map.addOverlay(marker);
//    marker.addEventListener('dragend',function(e){
//                panorama.setPosition(e.point); //拖动marker后,全景图位置也随着改变
//                panorama.setPov({heading: -40, pitch: 6});}
//    );
</script>
</body>
</html>

全屏

HTML5规范允许用户自定义网页上任一元素全屏显示。

开启/关闭全屏显示

方法如下:(注意 screen 是小写)

requestFullscreen()   //让元素开启全屏显示

cancleFullscreen()    //让元素关闭全屏显示

为考虑兼容性问题,不同的浏览器需要在此基础之上,添加私有前缀,比如:(注意 screen 是大写)

webkitRequestFullScreen
webkitCancleFullScreen

mozRequestFullScreen
mozCancleFullScreen

检测当前是否处于全屏状态

方法如下:

document.fullScreen

不同浏览器需要加私有前缀,比如:

document.webkitIsFullScreen

document.mozFullScreen

全屏的伪类

  • full-screen .box {}

  • -webkit-full-screen {}

  • moz-full-screen {}

比如说,当元素处于全屏状态时,改变它的样式。这时就可以用到伪类。

代码举例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>欢迎访问YYDNAS</title>
    <style>
        .box {
            width: 250px;
            height: 250px;
            background-color: green;
            margin: 100px auto;
            border-radius: 50%;
        }

        /*全屏伪类:当元素处于全屏时,改变元素的背景色*/
        .box:-webkit-full-screen {
            background-color: red;
        }
    </style>
</head>
</head>
<body>
    <div class="box"></div>

    <script>
        var box = document.querySelector('.box');
        // box.requestFullscreen();   //直接这样写是没有效果的。之所以无效,应该是浏览器的机制,必须要点一下才可以实现全屏功能。
        document.querySelector('.box').onclick = function () {
            // 开启全屏显示的兼容写法
            if (box.requestFullscreen) {  //如果支持全屏,那就让元素全屏
                box.requestFullscreen();
            } else if (box.webkitRequestFullScreen) {
                box.webkitRequestFullScreen();
            } else if (box.mozRequestFullScreen) {
                box.mozRequestFullScreen();
            }

        }
    </script>
</body>
</html>

效果如下:

HTML5详解(二)最先出现在Forever Young

]]>
https://www.luxiyue.com/learning/html5%e8%af%a6%e8%a7%a3%ef%bc%88%e4%ba%8c%ef%bc%89/feed/ 0
HTML5详解(一) https://www.luxiyue.com/learning/html5%e8%af%a6%e8%a7%a3%ef%bc%88%e4%b8%80%ef%bc%89/ https://www.luxiyue.com/learning/html5%e8%af%a6%e8%a7%a3%ef%bc%88%e4%b8%80%ef%bc%89/#respond Mon, 17 Apr 2023 04:37:23 +0000 https://www.luxiyue.com/?p=5450 HTML5的介绍 Web 技术发展时间线 1991 HTML 1994 HTML2 1996 CSS1 + JavaScript 1997 HTML4 1998 CSS2 2000 XHTML1(严格的html) 2002 Tableless Web Design(表格布局) 2005 AJAX 2009 HTML5 2014 HTML5 Finalized 2002年的表格布局逐渐被淘汰,是因为 […]

HTML5详解(一)最先出现在Forever Young

]]>
HTML5的介绍

Web 技术发展时间线

  • 1991 HTML

  • 1994 HTML2

  • 1996 CSS1 + JavaScript

  • 1997 HTML4

  • 1998 CSS2

  • 2000 XHTML1(严格的html)

  • 2002 Tableless Web Design(表格布局)

  • 2005 AJAX

  • 2009 HTML5

  • 2014 HTML5 Finalized

2002年的表格布局逐渐被淘汰,是因为:表格是用来承载数据的,并不是用来划分网页结构的。

2009年就已经推出了HTML5的草案,但直到2014年才有定稿,是因为有移动端的推动。

H5草案的前身是叫:Web Application,最早是由WHATWG这个组织在2004年提出的。

2007年被 W3C 组织接纳,并在 2008-01-22 发布 HTML5 的第一个草案。

什么是 HTML5

HTML5并不仅仅只是做为HTML标记语言的一个最新版本,更重要的是它制定了Web应用开发的一系列标准,成为第一个将Web做为应用开发平台的HTML语言。

HTML5定义了一系列新元素,如新语义标签、智能表单、多媒体标签等,可以帮助开发者创建富互联网应用,还提供了一些Javascript API,如地理定位、重力感应、硬件访问等,可以在浏览器内实现类原生应用。我们甚至可以结合 Canvas 开发网页版游戏。

HTML5的广义概念:HTML5代表浏览器端技术的一个发展阶段。在这个阶段,浏览器的呈现技术得到了飞跃发展和广泛支持,它包括:HTML5、CSS3、Javascript API在内的一套技术组合。

HTML5不等于 HTML next versionHTML5 包含: HTML的升级版、CSS的升级版、JavaScript API的升级版。

总结HTML5是新一代开发 Web 富客户端应用程序整体解决方案。包括:HTML5,CSS3,Javascript API在内的一套技术组合

富客户端:具有很强的交互性和体验的客户端程序。比如说,浏览博客,是比较简单的客户端;一个在线听歌的网站、即时聊天网站就是富客户端。

PS:

单纯地从技术的角度讲,兼容性问题只会让开发者徒增烦恼。

如果网页端的程序能做到PC客户端的体验,就会对后者构成威胁。

HTML5 的应用场景

列举几个HTML5 的应用场景:

  1. 极具表现力的网页:内容简约而不简单。

  2. 网页应用程序:

    • 代替PC端的软件:iCloud、百度脑图、Office 365等。

    • APP端的网页:淘宝、京东、美团等。

    • 微信端:公众号、小程序等。

  3. 混合式本地应用。

  4. 简单的游戏。

HTML5 新增的内容

语义化的标签

语义化的作用

语义标签对于我们并不陌生,如 <p> 表示一个段落、 <ul> 表示一个无序列表。标签语义化的作用:

  • 能够便于开发者阅读和写出更优雅的代码。

  • 同时让浏览器或是网络爬虫可以很好地解析,从而更好分析其中的内容。

  • 更好地搜索引擎优化。

总结:HTML的职责是描述一块内容是什么(或其意义),而不是它长什么样子;它的外观应该由CSS来决定。

H5在语义上的改进

在此基础上,HTML5 增加了大量有意义的语义标签,更有利于搜索引擎或辅助设备理解 HTML 页面内容。HTML5会让HTML代码的内容更结构化、标签更语义化。

我们常见的 css+div 布局是:

在html5中,我们可以这样写:

传统的做法中,我们通过增加类名如 class="header"class="footer" ,使HTML页面具有语义性,但是不具有通用性。

HTML5 则是通过新增语义标签的形式来解决这个问题,例如 <header></header><footer></footer> 等,这样就可以使其具有通用性。

传统网页布局:

<!-- 头部 -->
<div class="header">
    <ul class="nav"></ul>
</div>

<!-- 主体部分 -->
<div class="main">
    <!-- 文章 -->
    <div class="article"></div>
    <!-- 侧边栏 -->
    <div class="aside"></div>
</div>

<!-- 底部 -->
<div class="footer">

</div>

H5 的经典网页布局:

<!-- 头部 -->
<header>
    <ul class="nav"></ul>
</header>

<!-- 主体部分 -->
<div class="main">
    <!-- 文章 -->
    <article></article>
    <!-- 侧边栏 -->
    <aside></aside>
</div>

<!-- 底部 -->
<footer>

</footer>

H5中新增的语义标签

  • <section> 表示区块

  • <article> 表示文章。如文章、评论、帖子、博客

  • <header> 表示页眉

  • <footer> 表示页脚

  • <nav> 表示导航

  • <aside> 表示侧边栏。如文章的侧栏

  • <figure> 表示媒介内容分组。

  • <mark> 表示标记 (用得少)

  • <progress> 表示进度 (用得少)

  • <time> 表示日期

本质上新语义标签与 <div><span> 没有区别,只是其具有表意性,使用时除了在HTML结构上需要注意外,其它和普通标签的使用无任何差别,可以理解成 <div class="nav"> 相当于 <nav>

单标签不用写关闭符号。

新语义标签的兼容性处理

IE8 及以下版本的浏览器不支持 H5 和 CSS3。解决办法:引入 html5shiv.js 文件。

引入时,需要做if判断,具体代码如下:

<!--  条件注释 只有ie能够识别-->

<!--[if lte ie 8]>
    <script src="html5shiv.min.js"></script>
<![endif]-->

上方代码是条件注释:虽然是注释,但是IE浏览器可以识别出来。解释一下:

  • l:less 更小

  • t:than 比

  • e:equal等于

  • g:great 更大

我们在测试 IE 浏览器的兼容的时候,可以使用软件 ietest,模拟IE6-IE11。

在不支持HTML5新标签的浏览器,会将这些新的标签解析成行内元素(inline)对待,所以我们只需要将其转换成块元素(block)即可使用。

但是在IE9版本以下,并不能正常解析这些新标签,但是可以识别通过 document.createElement('tagName') 创建的自定义标签。于是我们的解决方案就是:将HTML5的新标签全部通过 document.createElement('tagName') 来创建一遍,这样IE低版本也能正常解析HTML5新标签了。

当然,在实际开发中我们更多采用的办法是:检测IE浏览器的版本,来加载第三方的JS库来解决兼容问题(如上方代码所示)。

H5中的表单

传统的Web表单已经越来越不能满足开发的需求,HTML5 在 Web 表单方向做了很大的改进,如拾色器、日期/时间组件等,使表单处理更加高效。

H5中新增的表单类型

  • email 只能输入email格式。自动带有验证功能。

  • tel 手机号码。

  • url 只能输入url格式。

  • number 只能输入数字。

  • search 搜索框

  • range 滑动条

  • color 拾色器

  • time 时间

  • date 日期

  • datetime 时间日期

  • month 月份

  • week 星期

上面的部分类型是针对移动设备生效的,且具有一定的兼容性,在实际应用当中可选择性的使用。

代码举例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
    <title>表单类型</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            background-color: #F7F7F7;
        }

        form {
            max-width: 500px;
            width: 100%;
            margin: 32px auto 0;
            font-size: 16px;
        }

        label {
            display: block;
            margin: 10px 0;
        }

        input {
            width: 100%;
            height: 25px;
            margin-top: 2px;
            display: block;
        }

    </style>
</head>
<body>
<form action="">
    <fieldset>
        <legend>表单类型</legend>
        <label for="">
            email: <input type="email" name="email" required>
        </label>
        <label for="">
            color: <input type="color" name="color">
        </label>
        <label for="">
            url: <input type="url" name='url'>
        </label>
        <label for="">
            number: <input type="number" step="3" name="number">
        </label>
        <label for="">
            range: <input type="range" name="range" value="100">
        </label>
        <label for="">
            search: <input type="search" name="search">
        </label>
        <label for="">
            tel: <input type="tel" name="tel">
        </label>
        <label for="">
            time: <input type="time" name="time">
        </label>
        <label for="">
            date: <input type="date" name="date">
        </label>
        <label for="">
            datetime: <input type="datetime">
        </label>
        <label for="">
            week: <input type="week" name="week">
        </label>
        <label for="">
            month: <input type="month" name="month">
        </label>
        <label for="">
            datetime-local: <input type="datetime-local" name="datetime-local">
        </label>
        <input type="submit">
    </fieldset>
</form>
</body>
</html>

代码解释:

<fieldset> 标签将表单里的内容进行打包,代表一组;而 <legend> 标签的则是 fieldset 里的元素定义标题。

表单元素(标签)

这里讲两个表单元素。

1、<datalist> 数据列表:

<input type="text" list="myData">
<datalist id="myData">
    <option>本科</option>
    <option>研究生</option>
    <option>不明</option>
</datalist>

上方代码中,input 里的 list 属性和 datalist 进行了绑定。

效果:

上图可以看出,数据列表可以自动提示。

2、<keygen>元素:

keygen 元素的作用是提供一种验证用户的可靠方法。

keygen 元素是密钥对生成器(key-pair generator)。当提交表单时,会生成两个键:一个公钥,一个私钥。

私钥(private key)存储于客户端,公钥(public key)则被发送到服务器。公钥可用于之后验证用户的客户端证书(client certificate)。

3、<meter>元素:度量器

  • low:低于该值后警告

  • high:高于该值后警告

  • value:当前值

  • max:最大值

  • min:最小值。

举例:

<meter  value="81"    min="0" max="100"  low="60"  high="80"/>

表单属性

  • placeholder 占位符(提示文字)

  • autofocus 自动获取焦点

  • multiple 文件上传多选或多个邮箱地址

  • autocomplete 自动完成(填充的)。on 开启(默认),off 取消。用于表单元素,也可用于表单自身(on/off)

  • form 指定表单项属于哪个form,处理复杂表单时会需要

  • novalidate 关闭默认的验证功能(只能加给form)

  • required 表示必填项

  • pattern 自定义正则,验证表单。例如

代码举例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        form {
            width: 100%;
            /* 最大宽度*/
            max-width: 640px;
            /* 最小宽度*/
            min-width: 320px;
            margin: 0 auto;
            font-family: "Microsoft Yahei";
            font-size: 20px;
        }

        input {
            display: block;
            width: 100%;
            height: 30px;
            margin: 10px 0;
        }
    </style>
</head>
<body>

<form action="">
    <fieldset>
        <legend>表单属性</legend>
        <label for="">
            用户名:<input type="text" placeholder="例如:smyhvae" autofocus name="userName" autocomplete="on" required/>
        </label>

        <label for="">
            电话:<input type="tel" pattern="1\d{10}"/>
        </label>

        <label for="">
            multiple的表单: <input type="file" multiple>
        </label>

        <!-- 上传文件-->
        <input type="file" name="file" multiple/>

        <input type="submit"/>
    </fieldset>
</form>

</body>
</html>

表单事件

  • oninput():用户输入内容时触发,可用于输入字数统计。

  • oninvalid():验证不通过时触发。比如,如果验证不通过时,想弹出一段提示文字,就可以用到它。

举例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        form {
            width: 100%;
            /* 最大宽度*/
            max-width: 400px;
            /* 最小宽度*/
            min-width: 200px;
            margin: 0 auto;
            font-family: "Microsoft Yahei";
            font-size: 20px;
        }

        input {
            display: block;
            width: 100%;
            height: 30px;
            margin: 10px 0;
        }
    </style>
</head>
<body>
<form action="">
    <fieldset>
        <legend>表单事件</legend>
        <label for="">
            邮箱:<input type="email" name="" id="txt1"/>
        </label>
        <label for="">
            输入的次数统计:<input type="text" name="" id="txt2"/>
        </label>

        <input type="submit"/>
    </fieldset>
</form>
<script>

    var txt1 = document.getElementById('txt1');
    var txt2 = document.getElementById('txt2');
    var num = 0;

    txt1.oninput = function () {  //用户输入时触发

        num++;  //用户每输入一次,num自动加 1
        //将统计数显示在txt2中
        txt2.value = num;
    }
    txt1.oninvalid = function () {  //验证不通过时触发
        this.setCustomValidity('亲,请输入正确哦');  //设置验证不通过时的提示文字
    }

</script>
</body>
</html>

效果:

多媒体

在HTML5之前,在网页上播放音频/视频的通用方法是利用Flash来播放。但是大多情况下,并非所有用户的浏览器都安装了Flash插件,由此使得音频、视频播放的处理变得非常复杂;并且移动设备的浏览器并不支持Flash插件。

H5里面提供了视频和音频的标签。

音频

HTML5通过 <audio> 标签来解决音频播放的问题。

使用举例:

<audio src="东风破.mp3" autoplay controls> </audio>

效果如下:

我们可以通过附加属性,来更友好地控制音频的播放,如:

  • autoplay 自动播放。写成autoplay 或者 autoplay = "",都可以。

  • controls 控制条。(建议把这个选项写上,不然都看不到控件在哪里)

  • loop 循环播放。

  • preload 预加载 同时设置 autoplay 时,此属性将失效。

处理兼容性问题:

由于版权等原因,不同的浏览器可支持播放的格式是不一样的:

为了做到多浏览器支持,可以采取以下兼容性写法:

<!--推荐的兼容写法:-->
<audio controls loop>
    <source src="music/yinyue.mp3"/>
    <source src="music/yinyue.ogg"/>
    <source src="music/yinyue.wav"/>
    抱歉,你的浏览器暂不支持此音频格式
</audio>

代码解释:如果识别不出音频格式,就弹出那句“抱歉”。

视频

HTML5通过 <video> 标签来解决视频播放的问题。

使用举例:

<video src="video/movie.mp4" controls autoplay></video>

我们可以通过附加属性,来更友好地控制视频的播放,如:

  • autoplay 自动播放。写成autoplay 或者 autoplay = "",都可以。

  • controls 控制条。(建议把这个选项写上,不然都看不到控件在哪里)

  • loop 循环播放。

  • preload 预加载 同时设置 autoplay 时,此属性将失效。

  • width:设置播放窗口宽度。

  • height:设置播放窗口的高度。

由于版权等原因,不同的浏览器可支持播放的格式是不一样的:

兼容性写法:

<!--<video src="video/movie.mp4" controls  autoplay ></video>-->
<!--  行内块 display:inline-block -->
<video controls autoplay>
    <source src="video/movie.mp4"/>
    <source src="video/movie.ogg"/>
    <source src="video/movie.webm"/>
    抱歉,不支持此视频
</video>

DOM 操作

获取元素

  • document.querySelector("selector") 通过CSS选择器获取符合条件的第一个元素。

  • document.querySelectorAll("selector") 通过CSS选择器获取符合条件的所有元素,以类数组形式存在。

类名操作

  • Node.classList.add("class") 添加class

  • Node.classList.remove("class") 移除class

  • Node.classList.toggle("class") 切换class,有则移除,无则添加

  • Node.classList.contains("class") 检测是否存在class

自定义属性

js 里可以通过 box1.index=100; box1.title 来自定义属性和获取属性。

H5可以直接在标签里添加自定义属性,但必须以 data- 开头

举例:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<!-- 给标签添加自定义属性 必须以data-开头 -->
<div class="box" title="盒子" data-my-name="smyhvae" data-content="我是一个div">div</div>
<script>
    var box = document.querySelector('.box');

    //自定义的属性 需要通过 dateset[]方式来获取
    console.log(box.dataset["content"]);  //打印结果:我是一个div
    console.log(box.dataset["myName"]);    //打印结果:smyhvae

    //设置自定义属性的值
    var num = 100;
    num.index = 10;
    box.index = 100;
    box.dataset["content"] = "aaaa";

</script>
</body>
</html>

举例:鼠标点击时,tab栏切换

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Tab 标签</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            background-color: #F7F7F7;
        }

        .tabs {
            width: 400px;
            margin: 30px auto;
            background-color: #FFF;
            border: 1px solid #C0DCC0;
            box-sizing: border-box;
        }

        .tabs nav {
            height: 40px;
            text-align: center;
            line-height: 40px;
            overflow: hidden;
            background-color: #C0DCC0;
            display: flex;
        }

        nav a {
            display: block;
            width: 100px;
            border-right: 1px solid #FFF;
            color: #000;
            text-decoration: none;
        }

        nav a:last-child {
            border-right: 0 none;
        }

        nav a.active {
            background-color: #9BAF9B;
        }

        .cont {
            overflow: hidden;
            display: none;
        }

        .cont ol {
            line-height: 30px;
        }
    </style>
</head>

<body>
    <div class="tabs">
        <nav>
            <a href="javascript:;" data-cont="local">国内新闻</a>
            <a href="javascript:;" data-cont="global">国际新闻</a>
            <a href="javascript:;" data-cont="sports">体育新闻</a>
            <a href="javascript:;" data-cont="funny">娱乐新闻</a>
        </nav>
        <section class="cont" id="local">
            <ol>
                <li>国内新闻1</li>
                <li>国内新闻2</li>
                <li>国内新闻3</li>
                <li>国内新闻4</li>
                <li>国内新闻5</li>
                <li>国内新闻6</li>
                <li>国内新闻7</li>
            </ol>
        </section>
        <section class="cont" id="global">
            <ol>
                <li>国内新闻1</li>
                <li>国际新闻2</li>
                <li>国际新闻3</li>
                <li>国际新闻4</li>
                <li>国际新闻5</li>
                <li>国际新闻6</li>
            </ol>
        </section>
        <section class="cont" id="sports">
            <ol>
                <li>体育新闻1</li>
                <li>体育新闻2</li>
                <li>体育新闻3</li>
                <li>体育新闻4</li>
                <li>体育新闻5</li>
                <li>体育新闻6</li>
                <li>体育新闻7</li>
            </ol>
        </section>
        <section class="cont" id="funny">
            <ol>
                <li>娱乐新闻1</li>
                <li>娱乐新闻2</li>
                <li>娱乐新闻3</li>
                <li>娱乐新闻4</li>
                <li>娱乐新闻5</li>
                <li>娱乐新闻6</li>
                <li>娱乐新闻7</li>
            </ol>
        </section>
    </div>
    <script>
        // 目标: 默认显示一个 当前的样式
        // 点击导航,实现切换
        // key 表示的当前显示的是第几个

        (function (key) {
            // 获取所有的导航
            var navs = document.querySelectorAll('nav a');
            // 遍历 给导航 绑定事件,并且添加当前样式
            for (var i = 0; i < navs.length; i++) {
                // 如果是用户指定的当前样式
                if (key == i) {
                    navs[i].classList.add('active');
                    // 拿到要显示内容section的id
                    var secId = navs[i].dataset['cont'];
                    // 获取对应的section标签
                    document.querySelector('#' + secId).style.display = 'block';
                }

                // 给每一个导航绑定点击事件
                navs[i].onclick = function () {
                    // 排他
                    // 之前有active样式的清除, 之前显示的section 隐藏
                    var currentNav = document.querySelector('.active');
                    // 获取对应的内容区域 ,让其隐藏
                    var currentId = currentNav.dataset['cont'];
                    // 去掉导航的active 样式
                    currentNav.classList.remove('active');
                    // 对应的内容区域
                    document.querySelector('#' + currentId).style.display = 'none';

                    // 突出显示自己 导航添加样式  对应的section 显示
                    // 给自己添加active样式
                    this.classList.add('active');
                    // 对应的section模块显示出来
                    var myId = this.dataset['cont'];
                    document.querySelector('#' + myId).style.display = 'block';
                }
            }

        })(0);

    </script>
</body>

</html>

HTML5详解(一)最先出现在Forever Young

]]>
https://www.luxiyue.com/learning/html5%e8%af%a6%e8%a7%a3%ef%bc%88%e4%b8%80%ef%bc%89/feed/ 0
HTML:05.其他标签 https://www.luxiyue.com/learning/html%ef%bc%9a05-%e5%85%b6%e4%bb%96%e6%a0%87%e7%ad%be/ https://www.luxiyue.com/learning/html%ef%bc%9a05-%e5%85%b6%e4%bb%96%e6%a0%87%e7%ad%be/#respond Thu, 13 Apr 2023 08:14:00 +0000 https://www.luxiyue.com/?p=5423 内容 列表标签:<ul>、<ol>、<dl> 表格标签:<table> 框架标签及内嵌框架<iframe> 表单标签:<form> 多媒体标签 滚动字幕标签:<marquee> 列表标签 列表标签分为三种。 1. 无序列表<ul>,无序列表中的每一项是<li> 英文单词解释如下: ul:un […]

HTML:05.其他标签最先出现在Forever Young

]]>
内容
  • 列表标签:<ul><ol><dl>

  • 表格标签:<table>

  • 框架标签及内嵌框架<iframe>

  • 表单标签:<form>

  • 多媒体标签

  • 滚动字幕标签:<marquee>

列表标签

列表标签分为三种。

1. 无序列表<ul>,无序列表中的每一项是<li>

英文单词解释如下:

  • ul:unordered list,“无序列表”的意思。

  • li:list item,“列表项”的意思。

例如:

<ul>
    <li>默认1</li>
    <li>默认2</li>
    <li>默认3</li>
</ul>

效果:

注意:

  • li 不能单独存在,必须包裹在 ul 里面;反过来说,ul 的“儿子”不能是别的东西,只能有 li

  • 我们这里再次强调,ul 的作用,并不是给文字增加小圆点的,而是增加无序列表的“语义”的。

属性:

  • type="属性值"。属性值可以选: disc(实心原点,默认),square(实心方点),circle(空心圆)。

效果如下:

不光是 <ul> 标签有 type 属性,<ul> 里面的 <li> 标签也有 type 属性(虽然说这种写法很少见)。效果如下:

注意:项目符号可以是图片,需要通过CSS设置 <li> 标记的背景图片来实现。

当然了,列表之间是可以嵌套的。我们来举个例子。代码:

<ul>
    <li><b>北京市</b>
        <ul>
            <li>海淀区</li>
            <li>朝阳区</li>
            <li>东城区</li>
        </ul>
    </li>

    <li><b>广州市</b>
        <ul>
            <li>天河区</li>
            <li>越秀区</li>
        </ul>
    </li>
</ul>

效果:

css 属性

list-style-position: inside   /* 给 ul 设置这个属性后,将小圆点包含在 li 元素的内部 */

ul标签实际应用场景:

场景1、导航条:

场景2、li 里面放置的内容可能很多:

声明:ul的儿子,只能是li。但是li是一个容器级标签,li里面什么都能放,甚至可以再放一个ul

2. 有序列表<ol>,里面的每一项是<li>

英文单词:Ordered List。

例如:

<ol >
    <li>呵呵哒1</li>
    <li>呵呵哒2</li>
    <li>呵呵哒3</li>
</ol>

效果:

属性:

  • type="属性值"。属性值可以是:1(阿拉伯数字,默认)、a、A、i、I。结合start属性表示从几开始

举例:

<ol type="1">
    <li>呵呵</li>
    <li>呵呵</li>
    <li>呵呵</li>
</ol>

<ol type="a">
    <li>嘿嘿</li>
    <li>嘿嘿</li>
    <li>呵呵</li>
</ol>

<ol type="i" start="4">
    <li>哈哈</li>
    <li>哈哈</li>
    <li>哈哈</li>
</ol>

<ol type="I" start="10">
    <li>么么</li>
    <li>么么</li>
    <li>么么</li>
</ol>

效果如下:

和无序列表一样,有序列表也是可以嵌套的哦,这里就不举类似的例子了。

olul 就是语义不一样,怎么使用都是一样的。

ol 里面只能有 lili 必须被 ol 包裹。li 是容器级。

ol 这个东西用的不多,如果想表达顺序,大家一般也用 ul 。举例如下:

<ul>
    <li>1. 小苹果</li>
    <li>2. 月亮之上</li>
    <li>3. 最炫民族风</li>
</ul>

3. 定义列表<dl>

定义列表的作用非常大。

<dl>英文单词:definition list,没有属性。dl的子元素只能是dt和dd。

  • <dt>:definition title 列表的标题,这个标签是必须的

  • <dd>:definition description 列表的列表项,如果不需要它,可以不加

备注:dt、dd只能在dl里面;dl里面只能有dt、dd。

举例:

<dl>
    <dt>第一条</dt>
    <dd>你若是觉得你有实力和我玩,良辰不介意奉陪到底</dd>
    <dd>我会让你明白,我从不说空话</dd>
    <dd>我是本地的,我有一百种方式让你呆不下去;而你,无可奈何</dd>

    <dt>第二条</dt>
    <dd>良辰最喜欢对那些自认能力出众的人出手</dd>
    <dd>你可以继续我行我素,不过,你的日子不会很舒心</dd>
    <dd>你只要记住,我叫叶良辰</dd>
    <dd>不介意陪你玩玩</dd>
    <dd>良辰必有重谢</dd>

</dl>

效果:

上图可以看出,定义列表表达的语义是两层:

  • 是一个列表,列出了几个 dd 项目

  • 每一个词儿都有自己的描述项

备注:dd 是描述 dt 的。

定义列表用法非常灵活,可以一个dt配很多dd:

<dl>
    <dt>北京</dt>
    <dd>国家首都,政治文化中心</dd>
    <dd>污染很严重,PM2.0天天报表</dd>
    <dt>上海</dt>
    <dd>魔都,有外滩、东方明珠塔、黄浦江</dd>
    <dt>广州</dt>
    <dd>中国南大门,有珠江、小蛮腰</dd>
</dl>

还可以拆开,让每一个dl里面只有一个dt和dd,这样子感觉清晰一些:

<dl>
    <dt>北京</dt>
    <dd>国家首都,政治文化中心</dd>
    <dd>污染很严重,PM2.0天天报表</dd>
</dl>

<dl>
    <dt>上海</dt>
    <dd>魔都,有外滩、东方明珠塔、黄浦江</dd>
</dl>

<dl>
    <dt>广州</dt>
    <dd>中国南大门,有珠江、小蛮腰</dd>
</dl>

真实案例:(京东最下方)

上图中的结构如下:

<dl>
    <dt>购物指南</dt>
    <dd>
        <a href="#">购物流程</a>
        <a href="#">会员介绍</a>
        <a href="#">生活旅行/团购</a>
        <a href="#">常见问题</a>
        <a href="#">大家电</a>
        <a href="#">联系客服</a>
    </dd>
</dl>
<dl>
    <dt>配送方式</dt>
    <dd>
        <a href="#">上门自提</a>
        <a href="#">211限时达</a>
        <a href="#">配送服务查询</a>
        <a href="#">配送费收取标准</a>
        <a href="#">海外配送</a>
    </dd>
</dl>

京东商品分类如下:

dtdd 都是容器级标签,想放什么都可以。所以,现在就应该更加清晰的知道:用什么标签,不是根据样子来决定,而是语义(语义本质上是结构)。

表格标签

表格标签用 <table> 表示。

一个表格 <table> 是由每行 <tr> 组成的,每行是由每个单元格 <td> 组成的。

所以我们要记住,一个表格是由行组成的(行是由列组成的),而不是由行和列组成的。

在以前,要想固定标签的位置,唯一的方法就是表格。现在可以通过CSS定位的功能来实现。但是现在在做页面的时候,表格作用还是有一些的。

例如,一行的单元格:

<table>
    <tr>
        <td></td>
        <td></td>
        <td></td>
        <td></td>
    </tr>
</table>

上面的表格中没有加文字,所以在生成的网页中什么都看不到。

例如,3行4列的单元格:

<table>
<tr>
    <td>许嵩</td>
    <td>29</td>
    <td>男</td>
    <td>安徽</td>
</tr>

<tr>
    <td>邓紫棋</td>
    <td>23</td>
    <td>女</td>
    <td>香港</td>
</tr>
</table>

效果:

上图中的表格好像没看到边框呀,不急,接下来看看 <table> 标签的属性。

<table>的属性:

  • border:边框。像素为单位。

  • style="border-collapse:collapse;":单元格的线和表格的边框线合并(表格的两边框合并为一条)

  • width:宽度。像素为单位。

  • height:高度。像素为单位。

  • bordercolor:表格的边框颜色。

  • align表格的水平对齐方式。属性值可以填:left right center。

    注意:这里不是设置表格里内容的对齐方式,如果想设置内容的对齐方式,要对单元格标签<td>进行设置)

  • cellpadding:单元格内容到边的距离,像素为单位。默认情况下,文字是紧挨着左边那条线的,即默认情况下的值为0。

    注意不是单元格内容到四条边的距离哈,而是到一条边的距离,默认是与左边那条线的距离。如果设置属性dir="rtl",那就指的是内容到右边那条线的距离。

  • cellspacing:单元格和单元格之间的距离(外边距),像素为单位。默认情况下的值为0

  • bgcolor="#99cc66":表格的背景颜色。

  • background="路径src/...":背景图片。

    背景图片的优先级大于背景颜色。

  • bordercolorlight:表格的上、左边框,以及单元格的右、下边框的颜色

  • bordercolordark:表格的右、下边框,以及单元格的上、左的边框的颜色

    这两个属性的目的是为了设置3D的效果。

  • dir:公有属性,单元格内容的排列方式(direction)。 可以取值:ltr:从左到右(left to right,默认),rtl:从右到左(right to left)

既然说 dir 是共有属性,如果把这个属性放在任意标签中,那表明这个标签的位置可能会从右开始排列。

单元格带边框的效果:

备注:表格中很细表格边线的制作,CSS的写法:

style="border-collapse:collapse;"

<tr>:行

一个表格就是一行一行组成的。

属性:

  • dir:公有属性,设置这一行单元格内容的排列方式。可以取值:

    • ltr:从左到右(left to right,默认)

    • rtl:从右到左(right to left)

  • bgcolor:设置这一行的单元格的背景色。

    注:没有background属性,即:无法设置这一行的背景图片,如果非要设置,可以用css实现。

  • height:一行的高度

  • align="center":一行的内容水平居中显示,取值:left、center、right

  • valign="center":一行的内容垂直居中,取值:top、middle、bottom

<td>:单元格

属性:

  • align:内容的横向对齐方式。属性值可以填:left right center。如果想让每个单元格的内容都居中,这个属性太麻烦了,以后用css来解决。

  • valign:内容的纵向对齐方式。属性值可以填:top middle bottom

  • width:绝对值或者相对值(%)

  • height:单元格的高度

  • bgcolor:设置这个单元格的背景色。

  • background:设置这个单元格的背景图片。

单元格的合并

单元格的属性:

  • colspan:横向合并。例如colspan="2"表示当前单元格在水平方向上要占据两个单元格的位置。

  • rowspan:纵向合并。例如rowspan="2"表示当前单元格在垂直方向上要占据两个单元格的位置。

效果举例:(横向合并)

效果举例:(纵向合并)

<th>:加粗的单元格。相当于<td> + <b>

  • 属性同<td>标签。

<caption>:表格的标题。使用时和tr标签并列

  • 属性:align,表示标题相对于表格的位置。属性取值可以是:left、center、right、top、bottom

效果:

表格的<thead>标签、<tbody>标签、<tfoot>标签

这三个标签有与没有的区别:

  • 如果写了,那么这三个部分的代码顺序可以任意,浏览器显示的时候还是按照thead、tbody、tfoot的顺序依次来显示内容。如果不写thead、tbody、tfoot,那么浏览器解析并显示表格内容的时候是从按照代码的从上到下的顺序来显示。

  • 当表格非常大内容非常多的时候,如果用thead、tbody、tfoot标签的话,那么数据可以边获取边显示。如果不写,则必须等表格的内容全部从服务器获取完成才能显示出来。

举例:

<table border="1">
    <tfoot>
    <tr>
        <td>许嵩</td>
        <td>29</td>
        <td>男</td>
        <td>安徽</td>
    </tr>
    </tfoot>
    <tbody>
    <tr>
        <td>邓紫棋</td>
        <td>23</td>
        <td>女</td>
        <td>香港</td>
    </tr>
    </tbody>
    <thead>
        <tr>
            <td>姓名</td>
            <td>年龄</td>
            <td>性别</td>
            <td>地点</td>
        </tr>
    </thead>

效果:

框架标签

如果我们希望在一个网页中显示多个页面,那框架标签就派上用场了。

注意:

  • 框架标签不能放在<body>标签里面,因为<body>标签代表的只是一个页面,而框架标签代表的是多个页面。于是:<frameset><body>只能二选一。

  • 框架的集合用<frameset>表示,然后在<frameset>集合里放入一个一个的框架<frame>

补充framesetframe已经从 Web标准中删除,建议使用 iframe 代替。

<frameset>:框架的集合

一个框架的集合可以包含多个框架或框架的集合。属性:

  • rows:水平分割,将框架分为上下部分。写法有两种:

1、绝对值写法:rows="200,*" 其中*代表剩余的。这里其实包含了两个框架:上面的框架占200个像素,下面的框架占剩下的部分。

2、相对值写法:rows="30%,*" 其中*代表剩余的。这里其实包含了两个框架:上面的框架占30%,下面的框架占70%。

注:如果你想将框架分成很多行,在属性值里用逗号隔开就行了。

  • cols:垂直分割,将框架分为左右部分。写法有两种:

1、绝对值写法:cols="200,*" 其中*代表剩余的。这里其实包含了两个框架:左边的框架占200个像素,右边的框架占剩下的部分。

2、相对值写法:cols="30%,*" 其中*代表剩余的。这里其实包含了两个框架:左边的框架占30%,右边的框架占70%。

注:如果你想将框架分成很多列,在属性值里用逗号隔开就行了。

<frame>:框架

一个框架显示一个页面。

属性:

  • scrolling="no":是否需要滚动条。默认值是 true

  • noresize:不可以改变框架大小。默认情况下,单个框架的边界是可以拖动的,这样的话,框架大小就不固定了。如果用了这个属性值,框架大小将固定。

举例:

<frame src="top.html" noresize></frame>
  • bordercolor="#00FF00" :给框架的边框定义颜色。这个属性在框架集合 <frameset> 中同样适用。

  • frameborder="0"frameborder="1" :隐藏或显示边框(框架线)。

  • name :给框架起一个名字。

利用 name 这个属性,可以在框架里进行超链。

内嵌框架

内嵌框架用 <iframe> 表示。 <iframe><body> 的子标记。

内嵌框架 inner frame :嵌入在一个页面上的框架(仅仅IE、新版google浏览器支持,可能有其他浏览器也支持,暂时我不清楚)。

属性:

  • src="subframe/the_second.html":内嵌的那个页面

  • width=800:宽度

  • height=“150:高度

  • scrolling="no":是否需要滚动条。默认值是true

  • name="mainFrame":窗口名称。公有属性

效果:

内嵌框架举例:(在内嵌页面中切换显示不同的页面)

<body>
    <a href="top.html" target="myframe">默认显示top页面</a><br>
    <a href="left.html" target="myframe">点击进入left页面</a><br>
    <a href="right.html" target="myframe">点击进入right页面</a><br>

    <iframe src="new.html" width="400" height="400" name="myframe"></iframe>
</body>

效果演示:

表单标签

表单标签用 <form> 表示,用于与服务器的交互。表单就是收集用户信息的,就是让用户填写的、选择的。

属性:

  • name:表单的名称,用于JS来操作或控制表单时使用;

  • id:表单的名称,用于JS来操作或控制表单时使用;

  • action:指定表单数据的处理程序,一般是PHP,如:action="login.php"

  • method:表单数据的提交方式,一般取值:get(默认)和 post

注意:表单和表格嵌套时,是在 <form> 标记中套 <table> 标记。

form标签里面的action属性和method属性,在后续的 ajax文章上再讲。这里简单说一下:action属性就是表示,表单将提交到哪里。 method属性表示用什么HTTP方法提交,有get、post两种。

get提交和post提交的区别:

GET方式:

将表单数据,以"name=value"形式追加到action指定的处理程序的后面,两者间用"?"隔开,每一个表单的"name=value"间用"&"号隔开。

特点:只适合提交少量信息,并且不太安全(不要提交敏感数据)、提交的数据类型只限于ASCII字符。

POST方式:

将表单数据直接发送(隐藏)到action指定的处理程序。POST发送的数据不可见。Action指定的处理程序可以获取到表单数据。

特点:可以提交海量信息,相对来说安全一些,提交的数据格式是多样的(Word、Excel、rar、img)。

Enctype:

表单数据的编码方式(加密方式),取值可以是:application/x-www-form-urlencodedmultipart/form-data。Enctype只能在POST方式下使用。

  • Application/x-www-form-urlencoded默认加密方式,除了上传文件之外的数据都可以

  • Multipart/form-data上传附件时,必须使用这种编码方式

<input>:输入标签(文本框)

用于接收用户输入。

<input type="text" />

属性:

  • type="属性值":文本类型。属性值可以是:

    • text(默认)

    • password:密码类型

    • radio:单选按钮,名字相同的按钮作为一组进行单选(单选按钮,天生是不能互斥的,如果想互斥,必须要有相同的name属性。name就是“名字”)。非常像以前的收音机,按下去一个按钮,其他的就抬起来了。所以叫做radio。

    • checkbox:多选按钮,name 属性值相同的按钮作为一组进行选择。

    • checked:将单选按钮或多选按钮默认处于选中状态。当<input>标签设置为type="radio"或者type=checkbox时,可以用这个属性。属性值也是checked,可以省略。

    • hidden:隐藏框,在表单中包含不希望用户看见的信息

    • button:普通按钮,结合js代码进行使用。

    • submit:提交按钮,传送当前表单的数据给服务器或其他程序处理。这个按钮不需要写value自动就会有“提交”文字。这个按钮真的有提交功能。点击按钮后,这个表单就会被提交到form标签的action属性中指定的那个页面中去。

    • reset:重置按钮,清空当前表单的内容,并设置为最初的默认值

    • image:图片按钮,和提交按钮的功能完全一致,只不过图片按钮可以显示图片。

    • file:文件选择框。

    提示:如果要限制上传文件的类型,需要配合JS来实现验证。对上传文件的安全检查:一是扩展名的检查,二是文件数据内容的检查。

    • value="内容":文本框里的默认内容(已经被填好了的)

    • size="50":表示文本框内可以显示五十个字符。一个英文或一个中文都算一个字符。

    注意size属性值的单位不是像素哦

    • readonly:文本框只读,不能编辑。因为它的属性值也是readonly,所以属性值可以不写。

    • disabled:文本框只读,不能编辑,光标点不进去。属性值可以不写。

备注:HTML5中,input的类型又增加了很多(比如date、color)。

举例

<form>
    姓名:<input value="呵呵" >逗比<br>
    昵称:<input value="哈哈" readonly=""><br>
    名字:<input type="text" value="name" disabled=""><br>
    密码:<input type="password" value="pwd" size="50"><br>
    性别:<input type="radio" name="gender" id="radio1" value="male" checked="">男
          <input type="radio" name="gender" id="radio2" value="female" >女<br>
    爱好:<input type="checkbox" name="love" value="eat">吃饭
          <input type="checkbox" name="love" value="sleep">睡觉
          <input type="checkbox" name="love" value="bat">打豆豆
</form>

效果:

注意,多个单选框的input标签中,name 的属性值可以相同,但是 id 的属性值必须是唯一的。我们知道,html的标签中,id的属性值是唯一的。

四种按钮的举例

<form>
    <input type="button" value="普通按钮"><br>
    <input type="submit"  value="提交按钮"><br>
    <input type="reset" value="重置按钮"><br>
    <input type="image" src="1.jpg" width="50" value="图片按钮"><br>
    <input type="file" value="文件选择框">
</form>

前端开发工程师,重点关心页面的美、样式、板式、交互。至于数据的提供和比较重的业务逻辑,都是后台工程师做的事情。

效果:

<select>:下拉列表标签

<select> 标签里面的每一项用 <option> 表示。select就是“选择”,option“选项”。

select 标签 和 uloldl 一样,都是组标签。

<select>标签的属性:

  • multiple:可以对下拉列表中的选项进行多选。属性值为 multiple,也可以没有属性值。也就是说,既可以写成 multiple="",也可以写成multiple="multiple"

  • size="3":如果属性值大于1,则列表为滚动视图。默认属性值为1,即下拉视图。

<option>标签的属性:

  • selected:预选中。没有属性值。

举例:

<form>
    <select>
        <option>小学</option>
        <option>初中</option>
        <option>高中</option>
        <option>大学</option>
        <option selected="">研究生</option>
    </select>
    <br><br><br>

    <select size="3">
        <option>小学</option>
        <option>初中</option>
        <option>高中</option>
        <option>大学</option>
        <option>研究生</option>
    </select>
    <br><br><br>

    <select multiple="">
        <option>小学</option>
        <option>初中</option>
        <option selected="">高中</option>
        <option selected="">大学</option>
        <option>研究生</option>
    </select>
    <br><br><br>

</form>

效果:

<textarea>标签:多行文本输入框

text 就是“文本”,area 就是“区域”。

属性:

  • rows="4":指定文本区域的行数。

  • cols="20":指定文本区域的列数。

  • readonly:只读。

举例:

<form>
    <textarea name="txtInfo" rows="4" cols="20">1、不爱摄影不懂设计的程序猿不是一个好的产品经理。</textarea>

    <textarea name="txtInfo" rows="4" cols="20">
        2、不爱摄影不懂设计的程序猿不是一个好的产品经理。</textarea>

    <textarea name="txtInfo" rows="4" cols="20">

        3、不爱摄影不懂设计的程序猿不是一个好的产品经理。</textarea>
</form>

效果:

上图的红框部分表示,我在文本区域进行了换行,所以显示的效果也出现了空白。

表单的语义化

比如,我们在注册一个网站的信息的时候,有一部分是必填信息,有一部分是选填信息,这个时候可以利用表单的语义化。
举例:

<form>

    <fieldset>
    <legend>账号信息</legend>
    姓名:<input value="呵呵" >逗比<br>
    密码:<input type="password" value="pwd" size="50"><br>
    </fieldset>

    <fieldset>
    <legend>其他信息</legend>
    性别:<input type="radio" name="gender" value="male" checked="">男
          <input type="radio" name="gender" value="female" >女<br>
    爱好:<input type="checkbox" name="love" value="eat">吃饭
          <input type="checkbox" name="love" value="sleep">睡觉
          <input type="checkbox" name="love" value="bat">打豆豆
    </fieldset>

</form>

效果:

<label>标签

我们先来看下面一段代码:

<input type="radio" name="sex" /> 男
<input type="radio" name="sex" /> 女

对于上面这样的单选框,我们只有点击那个单选框(小圆圈)才可以选中,点击“男”、“女”这两个文字时是无法选中的;于是,label标签派上了用场。

本质上来讲,“男”、“女”这两个文字和input标签时没有关系的,而label就是解决这个问题的。我们可以通过label把input和汉字包裹起来作为整体。

解决方法如下:

<input type="radio" name="sex" id="nan" /> <label for="nan">男</label>
<input type="radio" name="sex" id="nv"  /> <label for="nv">女</label>

上方代码中,让label标签的for 属性值,和 input 标签的 id 属性值相同,那么这个label和input就有绑定关系了。

当然了,复选框也有label:(任何表单元素都有label)

<input type="checkbox" id="kk" />
<label for="kk">10天内免登陆</label>

多媒体标签

声明:

多媒体包含:音频、视频、Flash。网页上的多媒体基本都是Flash格式的。

.wmv.dat.mob.rmvb 等视频格式,在网页上不能直接播放,需要安装第三方的插件,才可以播放。不同的浏览器,播客上述视频格式,所使用插件参数又不一样。

上述格式视频一般文件较大,不利于网络下载播放。

一般情况下,是将其它的视频格式,转成Flash来在网页上播放。转换软件:格式工厂等。

Flash格式的视频兼容性非常好,Flash格式的文件很小。

<bgsound>标签:播放背景音乐

属性:

  • src="音乐文件的路径"

  • loop="-1":属性值代表播放次数,-1代表循环播放。

举例:

<body>
    <bgsound src="王菲 - 清风徐来.mp3"></bgsound>
</body>

运行效果:

打开网页后,在IE 8中播放正常,播放时网页上显示一片空白。在google浏览器中无法播放。

<embed>标签:播放多媒体文件(音频、视频等)

主要应用Netscape浏览器,它不是W3C规范。

备注:视频格式可以支持 mp4、wav等,但不是所有视频格式都支持。

属性:

  • src="多媒体文件的路径"

  • loop="-1":属性值代表播放次数,-1代表循环播放。

  • autostart="false":打开网页时,禁止自动播放。默认值是true。

  • volume="100":设置默认的音量大小,测试发现这个值好像不起作用哦。

  • width:指Flash文件的宽度

  • height:指Flash文件的高度

  • quality:指Flash的播放质量,质量有高有低 hight low

  • pluginspage:如果指定的Flash插件不存在,则从 pluginspage 指定的地方进行下载。

  • type:指定Flash的文件格式类型

  • wmode:指Flash的背景是否可以透明,取值:transparent 是透明的

<object>标签:播放多媒体文件(音频、视频等)

主要应用IE浏览器,它是W3C规范。

属性:

  • classid:指定Flash插件的ID号,一般存在于注册表中。

  • codebase:如果Flash插件不存在,则从codebase指定的地址下载。

  • <param>标签的主要作用:设置具体的详细参数。

总结:在网页中插入Flash时,为了同时兼容多种浏览器,需要将 <object> 标签和 <embed> 标签标记一起使用,但使用的顺序是:<object> 中嵌套 <embed> 标记。

举例:

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0" width="778" height="202">
    <param name="movie" value="images/banner.swf">
    <param name="quality" value="high">
    <param name="wmode" value="transparent">
    <embed src="images/banner.swf" width="778" height="202" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" wmode="transparent"></embed>
</object>

<marquee>:滚动字幕标签

如果在这个标签里设置了内容,那么,打开网页时,内容会像弹幕一样自动移动。

属性:

  • direction="right":移动的目标方向。属性值可以是:left(从右向左移动,默认值)、right(从左向右移动)、up(从下向上移动)、down(从上向下移动)。

  • behavior="slide":行为方式。属性值可以是:slide(只移动一次)、scroll(循环移动,默认值)、alternate(循环移动)、。
    alternatescroll属性值都是循环移动,区别在于:假设在direction="right"的情况下,behavior="scroll"表示从左到右、从左到右、从左到右···behavior="alternate"表示从左到右、从右到左、从左到右···

  • scrollamount="30":移动的速度

  • loop="3": 循环多少圈。负值表示无限循环

  • scrolldelay="1000":移动一次休息多长时间。单位是毫秒。

举例:

<marquee behavior="alternate" direction="down"  width="300" height="200" bgcolor="#8c5dc1">我来了</marquee>

html废弃标签介绍

HTML现在只负责语义,而不负责样式。但是HTML一开始,连样式也包办了。这些样式的标签,都已经被废弃。

2004年之前的东西:

<font size="9" color="red">哈哈</font>

下面这些标签都是css钩子,而不是原意:

<b>加粗</b>
<u>下划线</u>
<i>倾斜</i>
<del>删除线</del>
<em>强调</em>
<strong>强调</strong>

这些标签,是有着浓厚的样式的作用,干涉了css的作用,所以HTML抛弃了他们。

类似的还有水平线标签:

<hr />

换行标签:

<br />

但是,网页中99.9999%需要换行的时候,是因为另起了一个段落,所以要用p,而不要用<br />。不到万不得已,不要用br标签。

标准的div+css页面,只会用到种类很少的标签:

<div>  <p>  <h1>  <span>   <a>   <img>   <ul>   <ol>    <dl>    <input>

知道每个标签的特殊用法、属性。比如 a 标签,img 的属性。

HTML:05.其他标签最先出现在Forever Young

]]>
https://www.luxiyue.com/learning/html%ef%bc%9a05-%e5%85%b6%e4%bb%96%e6%a0%87%e7%ad%be/feed/ 0
关于包管理器npm、yarn和pnpm的一些总结 https://www.luxiyue.com/learning/%e5%85%b3%e4%ba%8e%e5%8c%85%e7%ae%a1%e7%90%86%e5%99%a8npm%e3%80%81yarn%e5%92%8cpnpm%e7%9a%84%e4%b8%80%e4%ba%9b%e6%80%bb%e7%bb%93/ https://www.luxiyue.com/learning/%e5%85%b3%e4%ba%8e%e5%8c%85%e7%ae%a1%e7%90%86%e5%99%a8npm%e3%80%81yarn%e5%92%8cpnpm%e7%9a%84%e4%b8%80%e4%ba%9b%e6%80%bb%e7%bb%93/#respond Thu, 13 Apr 2023 06:50:53 +0000 https://www.luxiyue.com/?p=5397 前言 在Node.js生态系统中,包管理器是至关重要的组件之一,它们负责维护各种应用程序和库之间的依赖关系。 依赖(dependency)是别人为了解决一些问题而写好的代码,即我们常说的第三方包或三方库。 一个项目或多或少的会有一些依赖,而你安装的依赖又可能有它自己的依赖。 项目中的依赖,可以是一个完整的库或者框架,比如 react 或 vue;可以是一个很小的功能,比如日期格式化;也可以是一个命 […]

关于包管理器npm、yarn和pnpm的一些总结最先出现在Forever Young

]]>
前言

在Node.js生态系统中,包管理器是至关重要的组件之一,它们负责维护各种应用程序和库之间的依赖关系。

依赖(dependency)是别人为了解决一些问题而写好的代码,即我们常说的第三方包或三方库。

一个项目或多或少的会有一些依赖,而你安装的依赖又可能有它自己的依赖。

项目中的依赖,可以是一个完整的库或者框架,比如 react 或 vue;可以是一个很小的功能,比如日期格式化;也可以是一个命令行工具,比如 eslint。

如果没有现代化的构建工具,即包管理器,你需要用 <script> 标签来引入依赖。

此外,如果你发现了一个比当前使用的依赖更好的库,或者你使用的依赖发布了更新,而你想用最新版本,在一个大的项目中,这些版本管理、依赖升级将是让人头疼的问题。

于是包管理器诞生了,用来管理项目的依赖。

它提供方法给你安装依赖(即安装一个包),管理包的存储位置,而且你可以发布自己写的包。

npm1

在Node.js生态系统中,包管理器是至关重要的组件之一,它们负责维护各种应用程序和库之间的依赖关系。npm(Node.js Package Manager)是Node.js的默认包管理器,它的初始版本是npm1,但是它很快就被npm2所取代。

npm2

关于npm2最初作为包管理管理,采用的是node_modules嵌套模式,即每个包都会有自己独立的node_modules,且会将各自依赖进行安装,依赖的依赖也会产生自己的node_modules,这样就产生了“嵌套依赖”。

就像回调嵌套一样,容易陷入回调地狱,嵌套依赖也不例外。

这种嵌套依赖的模式,虽然可以使依赖项的版本更加明确和稳定,但是在实际应用中也存在一些问题。其中最大的问题是包的嵌套层级很深,这可能会导致安装和更新依赖项的时间变长,并增加包的大小。此外,由于每个包都有自己的node_modules文件夹,这可能会导致文件系统中出现大量重复的依赖项,从而占用更多的磁盘空间。

npm install 原理

主要分为两个部分, 首先,执行 npm install 之后,包如何到达项目 node_modules 当中。其次,node_modules 内部如何管理依赖。

执行命令后,首先会构建依赖树,然后针对每个节点下的包,会经历下面四个步骤:

  1. 将依赖包的版本区间解析为某个具体的版本号;

  2. 下载对应版本依赖的 tar 包到本地离线镜像;

  3. 将依赖从离线镜像解压到本地缓存;

  4. 将依赖从缓存拷贝到当前目录的 node_modules 目录;

然后,对应的包就会到达项目的node_modules当中。

在 npm1、npm2 中呈现出的是嵌套结构,比如下面这样:

这会导致3个问题:

  1. 依赖层级太深,会导致文件路径过长的问题,尤其在 window 系统下;

  2. 大量重复的包被安装,文件体积超级大。比如跟 foo 同级目录下有一个baz,两者都依赖于同一个版本的lodash,那么 lodash 会分别在两者的 node_modules 中被安装,也就是重复安装;

  3. 模块实例不能共享。比如 React 有一些内部变量,在两个不同包引入的 React 不是同一个模块实例,因此无法共享内部变量,导致一些不可预知的 bug;

npm3/yarn

从 npm3 开始,包括 yarn,都着手来通过扁平化依赖的方式来解决上面的这个问题:

所有的依赖都被拍平到node_modules目录下,不再有很深层次的嵌套关系。这样在安装新的包时,根据 node require 机制,会不停往上级的node_modules当中去找,如果找到相同版本的包就不会重新安装,解决了大量包重复安装的问题,而且依赖层级也不会太深。

但是扁平化带来了新的问题:

  1. package.json里并没有写入的包竟然也可以在项目中使用了(Phantom - 幻影依赖)。

  2. node_modules安装的不稳定性(Doppelgangers - 分身依赖)。

  3. 平铺式的node_modules算法复杂,耗费时间。

Phantom

package.json 中我们只声明了A,B ~ F都是因为扁平化处理才放到和A同级的 node_modules 下,理论上在项目中写代码时只可以使用A,但实际上B ~ F也可以使用,由于扁平化将没有直接依赖的包提升到 node_modules 一级目录,Node.js没有校验是否有直接依赖,所以项目中可以非法访问没有声明过依赖的包。这种情况被称为“幽灵依赖”。

举个例子,假设有个项目需要依赖包 A 和 B,而这两个包都依赖于包 C,但是包 A 依赖于包 C 的版本 1.0.0,而包 B 依赖于包 C 的版本 2.0.0。在 npm2 中,这两个版本的包 C 会被分别安装在 A 和 B 的 node_modules 目录下,不会产生冲突。但在 npm3 中,这两个版本的包 C 可能会被安装在同一个 node_modules 目录下,这时候就会产生冲突,导致代码无法运行。

Doppelgangers

比如B和C都依赖了F,但是依赖的F版本不一样:

依赖结构的不确定性表现是扁平化的结果不确定,以下2种情况都有可能,取决于 package.json 中B和C的位置。

npm5.x/yarn - 带有lock文件的平铺式的node_modules

该版本引入了一个lock文件,以解决node_modules安装中的不确定因素。 这使得无论你安装多少次,都能有一个一样结构的node_modules。 这也是为什么lock文件应该始终包含在版本控制中并且不应该手动编辑的原因。

然而,平铺式的算法的复杂性,以及Phantom、性能和安全问题仍未得到解决。

pnpm - 基于符号链接的node_modules结构

什么是 pnpm

pnpm 本质上就是一个包管理器,这一点跟 npm/yarn 没有区别,但它作为杀手锏的优势在于:

  • 包安装速度极快

  • 磁盘空间利用非常高效

  • 支持 monorepo

  • 安全性高

它的安装也非常简单。可以有多简单?

npm i -g pnpm

特性概览

1. 速度快

pnpm 安装包的速度究竟有多快?先以 React 包为例来对比一下:

可以看到,作为黄色部分的 pnpm,在绝多大数场景下,包安装的速度都是明显优于 npm/yarn,速度会比 npm/yarn 快 2-3 倍。

2. 高效利用磁盘空间

  • npm/yarn - 消耗磁盘空间的node_modules

    npm/yarn有一个缺点,就是使用了太多的磁盘空间, 如果你安装同一个包100次,100分的就会被储存在不同的node_modules文件夹下。 举一个常有的的例子,如果完成了一个项目,而node_modules没有删掉保留了下来,往往会占用大量的磁盘空间。 为了解决这个问题,我经常使用npkill。

    npx npkill

    可以扫描当前文件夹下的所有node_modules,并动态地删除它们。

  • pnpm - 高效的使用磁盘空间

    pnpm将包存储在同一文件夹中(content-addressable store),只要当你在同一OS的同一个用户在下再次安装时就只需要创建一个硬链接。 MacOs的默认位置是~/.pnpm-store,甚至当安装同一package的不同版本时,只有不同的部分会被重新保存。 也就是说然后当你安装一个package时,如果它在store里,建立硬连接新使用,如果没有,就下载保存在store再创建硬连接。

    在使用 pnpm 对项目安装依赖的时候,如果某个依赖在 sotre 目录中存在了话,那么就会直接从 store 目录里面去 hard-link,避免了二次安装带来的时间消耗,如果依赖在 store 目录里面不存在的话,就会去下载一次。

    当然这里你可能也会有问题:如果安装了很多很多不同的依赖,那么 store 目录会不会越来越大?

    答案是当然会存在,针对这个问题,pnpm 提供了一个命令来解决这个问题: pnpm store | pnpm 。

    同时该命令提供了一个选项,使用方法为 pnpm store prune ,它提供了一种用于删除一些不被全局项目所引用到的 packages 的功能,例如有个包 axios@1.0.0 被一个项目所引用了,但是某次修改使得项目里这个包被更新到了 1.0.1 ,那么 store 里面的 1.0.0 的 axios 就就成了个不被引用的包,执行 pnpm store prune 就可以在 store 里面删掉它了。

    该命令推荐偶尔进行使用,但不要频繁使用,因为可能某天这个不被引用的包又突然被哪个项目引用了,这样就可以不用再去重新下载这个包了。

3. 支持 monorepo

随着前端工程的日益复杂,越来越多的项目开始使用 monorepo。之前对于多个项目的管理,我们一般都是使用多个 git 仓库,但 monorepo 的宗旨就是用一个 git 仓库来管理多个子项目,所有的子项目都存放在根目录的packages目录下,那么一个子项目就代表一个package。

pnpm 与 npm/yarn 另外一个很大的不同就是支持了 monorepo,体现在各个子命令的功能上,比如在根目录下 pnpm add A -r, 那么所有的 package 中都会被添加 A 这个依赖,当然也支持 –filter字段来对 package 进行过滤。

4. 安全性高

不知道你发现没有,pnpm 这种依赖管理的方式也很巧妙地规避了非法访问依赖的问题,也就是只要一个包未在 package.json 中声明依赖,那么在项目中是无法访问的。

但在 npm/yarn 当中是做不到的,那你可能会问了,如果 A 依赖 B, B 依赖 C,那么 A 就算没有声明 C 的依赖,由于有依赖提升的存在,C 被装到了 A 的node_modules里面,那我在 A 里面用 C,跑起来没有问题呀,我上线了之后,也能正常运行啊。不是挺安全的吗?

还真不是。

  1. 你要知道 B 的版本是可能随时变化的,假如之前依赖的是C@1.0.1,现在发了新版,新版本的 B 依赖 C@2.0.1,那么在项目 A 当中 npm/yarn install 之后,装上的是 2.0.1 版本的 C,而 A 当中用的还是 C 当中旧版的 API,可能就直接报错了。

  2. 如果 B 更新之后,可能不需要 C 了,那么安装依赖的时候,C 都不会装到node_modules里面,A 当中引用 C 的代码直接报错。

  3. 在 monorepo 项目中,如果 A 依赖 X,B 依赖 X,还有一个 C,它不依赖 X,但它代码里面用到了 X。由于依赖提升的存在,npm/yarn 会把 X 放到根目录的 node_modules 中,这样 C 在本地是能够跑起来的,因为根据 node 的包加载机制,它能够加载到 monorepo 项目根目录下的 node_modules 中的 X。但试想一下,一旦 C 单独发包出去,用户单独安装 C,那么就找不到 X 了,执行到引用 X 的代码时就直接报错了。

这些,都是依赖提升潜在的 bug。如果是自己的业务代码还好,试想一下如果是给很多开发者用的工具包,那危害就非常严重了。

pnpm生成node_modules主要分为两个步骤

1. 基于硬连接的node_modules

.
└── node_modules
    └── .pnpm
        ├── foo@1.0.0
        │   └── node_modules
        │       └── foo -> <store>/foo
        └── bar@1.0.0
            └── node_modules
                └── bar -> <store>/bar

乍一看,结构与npm/yarn的结构完全不同,第一手node_modules下面的唯一文件夹叫做 .pnpm 。在 .pnpm 下面是一个 <PACKAGE_NAME@VERSION> 文件夹,而在其下面 <PACKAGE_NAME> 的文件夹是一个content-addressable store的硬链接。 当然仅仅是这样还无法使用,所以下一步软链接也很关键。

2. 用于依赖解析的软链接

  • 用于在foo内引用bar的软链接

  • 在项目里引用foo的软链接

.
└── node_modules
    ├── foo -> ./.pnpm/foo@1.0.0/node_modules/foo
    └── .pnpm
        ├── foo@1.0.0
        │   └── node_modules
        │       ├── foo -> <store>/foo
        │       └── bar -> ../../bar@1.0.0/node_modules/bar
        └── bar@1.0.0
            └── node_modules
                └── bar -> <store>/bar

当然这只是使用pnpm的node_modules结构最简单的例子!但可以发现项目中能使用的代码只能是 package.json 中定义过的,并且完全可以做到没用无用的安装。peers dependencies的话会比这个稍微复杂一些,但一旦不考虑peer的话任何复杂的依赖都可以完全符合这种结构。

例如,当foo和bar同时依赖于lodash的时候,就会像下图这样的结构。

.
└── node_modules
    ├── foo -> ./.pnpm/foo@1.0.0/node_modules/foo
    └── .pnpm
        ├── foo@1.0.0
        │   └── node_modules
        │       ├── foo -> <store>/foo
        │       ├── bar -> ../../bar@1.0.0/node_modules/bar
        │       └── lodash -> ../../lodash@1.0.0/node_modules/lodash
        ├── bar@1.0.0
        │   └── node_modules
        │       ├── bar -> <store>/bar
        │       └── lodash -> ../../lodash@1.0.0/node_modules/lodash
        └── lodash@1.0.0
            └── node_modules
                └── lodash -> <store>/lodash

node_modules 中的 bar 和 foo 两个目录会软连接到 .pnpm 这个目录下的真实依赖中,而这些真实依赖则是通过 hard link 存储到全局的 store 目录中。

综合而言,本质上 pnpm 的 node_modules 结构是个网状 + 平铺的目录结构。这种依赖结构主要基于软连接(即 symlink)的方式来完成。

pnpm 是通过 hardlink 在全局里面搞个 store 目录来存储 node_modules 依赖里面的 hard link 地址,然后在引用依赖的时候则是通过 symlink 去找到对应虚拟磁盘目录下(.pnpm 目录)的依赖地址。

比如安装A,A依赖了B:

  1. 安装依赖

    A和B一起放到.pnpm中(和上面相比,这里没有耗时的扁平化算法)。

    另外A@1.0.0下面是node_modules,然后才是A,这样做有两点好处:

    • 允许包引用自身

    • 把包和它的依赖摊平,避免循环结构

  2. 处理间接依赖

    A平级目录创建B,B指向B@1.0.0下面的B。

  3. 处理直接依赖

    顶层node_modules目录下创建A,指向A@1.0.0下的A。

    对于更深的依赖,比如A和B都依赖了C:

pnpm以外的解決法

Yarn 要不要支持 symlinks(符号链接) 的讨论

2016 年 11 月 10 日,一个大佬开了一个 issue:Looking for brilliant yarn member who has first-hand knowledge of prior issues with symlinking modules。

问:「听@thejameskyle 说,在开源之前,Yarn 曾经做过 symlinks(符号链接)。然而,它破坏了太多的生态系统而不能被认为是一个有效的选择。」如果您是 yarn 成员,对实际损坏的内容有第一手消息,并且可以从技术上解释原因,我恳请您回答这个问题。

然后@sebmck 回答了他的问题:说 symlinks(符号链接),对现有的生态系统不能很好地兼容。

总结了几点:

符号链接的优点:

  1. 稍微快一点的包安装;

  2. 更少的磁盘使用;

存在的缺点:

  1. 操作系统差异;

  2. 通过添加多种安装模式来降低 Yarn 的确定性;

  3. 文件观察不兼容;

  4. 现有工具兼容性差;

  5. 由循环引起的递归错误,等等…

这个 issue,讨论了很长的篇幅,这里就不继续了,感兴趣的可以去观摩一下。最后显然 yarn 的团队暂时不打算支持使用符号链接。

npm global-style

npm也曾经为了解决扁平式node_modules的问题提供过,通过指定global-style来禁止平铺node_modules,但这无疑又退回了嵌套式的node_modules时代的问题,所以并没有推广开来。

dependency-check

光靠npm/yarn的话看似无法解决,所以基础社区的解决方案dependency-check也经常被用到。

$ dependency-check ./package.json --verbose
Success! All dependencies used in the code are listed in package.json
Success! All dependencies in package.json are used in the code

有了本文的基础,光是看到README内一段命令行的输出应该也能想象到dependency-check是如何工作的了吧!

果然和其他的解决方案比,pnpm显得最为优雅吧。

hard link 和 symlink 兼容问题

读到这里,可能有用户会好奇: 像 hard link 和 symlink 这种方式在所有的系统上都是兼容的吗?

实际上 hard link 在主流系统上(Unix/Win)使用都是没有问题的,但是 symlink 即软连接的方式可能会在 windows 存在一些兼容的问题,但是针对这个问题,pnpm 也提供了对应的解决方案:

在 win 系统上使用一个叫做 junctions 的特性来替代软连接,这个方案在 win 上的兼容性要好于 symlink。

或许你也会好奇为啥 pnpm 要使用 hard links 而不是全都用 symlink 来去实现。

实际上存在 store 目录里面的依赖也是可以通过软连接去找到的,nodejs 本身有提供一个叫做 -preserve-symlinks 的参数来支持 symlink,但实际上这个参数实际上对于 symlink 的支持并不好导致作者放弃了该方案从而采用 hard links 的方式。

npm/yarn 与 pnpm 对比小结

npm/yarn - 缺点

  • 扁平的node_modules结构允许访问没有引用的package。

  • 来自不同项目的package不能共享,这是对磁盘空间的消耗。

  • 安装缓慢,大量重复安装node_modules。

pnpm - 解决方案

  • pnpm使用独创的基于symlink的node_modules结构,只允许访问package.json中的引入packages(严格)。

  • 安装的package存储在一个任何文件夹都可以访问的目录里并用硬连接到各个node_modules,以节省磁盘空间(高效)。

  • 有了上述改变,安装也会更快(快速)。

从官方网站上看,严格、高效、快速和对于monorepo的支持是pnpm的四大特点。

pnpm 日常使用

说了这么多,估计你会觉得 pnpm 挺复杂的,是不是用起来成本很高呢?

恰好相反,pnpm 使用起来十分简单,如果你之前有 npm/yarn 的使用经验,甚至可以无缝迁移到 pnpm 上来。不信我们来举几个日常使用的例子。

pnpm install

跟 npm install 类似,安装项目下所有的依赖。但对于 monorepo 项目,会安装 workspace 下面所有 packages 的所有依赖。不过可以通过 –filter 参数来指定 package,只对满足条件的 package 进行依赖安装。

当然,也可以这样使用,来进行单个包的安装:

// 安装 axios
pnpm install axios
// 安装 axios 并将 axios 添加至 devDependencies
pnpm install axios -D
// 安装 axios 并将 axios 添加至 dependencies
pnpm install axios -S

当然,也可以通过 -filter 来指定 package。

pnpm update

根据指定的范围将包更新到最新版本,monorepo 项目中可以通过 -filter 来指定 package。

pnpm uninstall

在 node_modules 和 package.json 中移除指定的依赖。monorepo 项目同上。举例如下:

// 移除 axios
pnpm uninstall axios --filter package-a

pnpm link

将本地项目连接到另一个项目。注意,使用的是硬链接,而不是软链接。如:

pnpm link ../../axios

另外,对于我们经常用到 npm run/start/test/publish,这些直接换成 pnpm 也是一样的,不再赘述。更多的使用姿势可参考官方文档。

总结

可以看到,虽然 pnpm 内部做了非常多复杂的设计,但实际上对于用户来说是无感知的,使用起来非常友好。并且,现在作者现在还一直在维护,目前 npm 上周下载量已经有 10w +,经历了大规模用户的考验,稳定性也能有所保障。

因此,我觉得无论是从背后的安全和性能角度,还是从使用上的心智成本来考虑,pnpm 都是一个相比 npm/yarn 更优的方案。

本文参考:前端包管理器对比 npm、yarn 和 pnpm 以及 关于包管理器Npm、Yarn和Pnpm的一些总结

关于包管理器npm、yarn和pnpm的一些总结最先出现在Forever Young

]]>
https://www.luxiyue.com/learning/%e5%85%b3%e4%ba%8e%e5%8c%85%e7%ae%a1%e7%90%86%e5%99%a8npm%e3%80%81yarn%e5%92%8cpnpm%e7%9a%84%e4%b8%80%e4%ba%9b%e6%80%bb%e7%bb%93/feed/ 0
markdown中转义字符源码显示 https://www.luxiyue.com/learning/markdown%e4%b8%ad%e8%bd%ac%e4%b9%89%e5%ad%97%e7%ac%a6%e6%ba%90%e7%a0%81%e6%98%be%e7%a4%ba/ https://www.luxiyue.com/learning/markdown%e4%b8%ad%e8%bd%ac%e4%b9%89%e5%ad%97%e7%ac%a6%e6%ba%90%e7%a0%81%e6%98%be%e7%a4%ba/#respond Thu, 13 Apr 2023 05:43:02 +0000 https://www.luxiyue.com/?p=5389 前言 最近遇到一个问题,当我在markdown中使用代码块包裹转义字符时,最终前端还是会将字符转义出来。 比如: &nbsp; #在前端仍然会输出为空格 解决方法 在Markdown中使用反引号包裹起来的文本会被解析为代码或者代码块,而不是普通的文本。 如果希望在Markdown中展示转义字符的源码,可以使用HTML实体编码的方式来实现。 在HTML实体编码中,&nbsp; 表示一 […]

markdown中转义字符源码显示最先出现在Forever Young

]]>
前言

最近遇到一个问题,当我在markdown中使用代码块包裹转义字符时,最终前端还是会将字符转义出来。

比如:

&nbsp;  #在前端仍然会输出为空格

解决方法

在Markdown中使用反引号包裹起来的文本会被解析为代码或者代码块,而不是普通的文本。

如果希望在Markdown中展示转义字符的源码,可以使用HTML实体编码的方式来实现。

在HTML实体编码中,&nbsp; 表示一个空格字符,如果您想要在Markdown中展示 &nbsp; 的源码,需要使用如下格式书写:

&amp;nbsp;

这样在Markdown中展示时,就会把上面代码作为普通文本处理,不会被解析成空格字符,同时在前端渲染时也不会被转义为空格,而是显示为 &nbsp; 的源码。

其他

其他转义字符的使用也是相同的。

markdown中转义字符源码显示最先出现在Forever Young

]]>
https://www.luxiyue.com/learning/markdown%e4%b8%ad%e8%bd%ac%e4%b9%89%e5%ad%97%e7%ac%a6%e6%ba%90%e7%a0%81%e6%98%be%e7%a4%ba/feed/ 0
HTML:04.图片标签 https://www.luxiyue.com/learning/html%ef%bc%9a04-%e5%9b%be%e7%89%87%e6%a0%87%e7%ad%be/ https://www.luxiyue.com/learning/html%ef%bc%9a04-%e5%9b%be%e7%89%87%e6%a0%87%e7%ad%be/#respond Mon, 03 Apr 2023 08:31:18 +0000 https://www.luxiyue.com/?p=4868 img标签介绍 介绍 img: 英文全称 image(图像),代表的是一张图片。 如果要想在网页中显示图像,就可以使用img 标签,它是一个单标签。语法如下: <img src="图片的URL" /> 能插入的图片类型 能够插入的图片类型是:jpg(jpeg)、gif、png、bmp等。 不能往网页中插入的图片格式是:psd、ai等。 HTML页面不是直接插入图片, […]

HTML:04.图片标签最先出现在Forever Young

]]>
img标签介绍

介绍

img: 英文全称 image(图像),代表的是一张图片。

如果要想在网页中显示图像,就可以使用img 标签,它是一个单标签。语法如下:

<img src="图片的URL" />

能插入的图片类型

  • 能够插入的图片类型是:jpg(jpeg)、gif、png、bmp等。

  • 不能往网页中插入的图片格式是:psd、ai等。

HTML页面不是直接插入图片,而是插入图片的引用地址,所以要先把图片上传到服务器上。

img标签的src属性

这里涉及到图片的一个属性:

  • src属性:指图片的路径。英文名称 source。

在写图片的路径时,有两种写法:相对路径、绝对路径

写法一:图片的相对路径

相对当前页面所在的路径。两个标记 ... 分表代表当前目录和上一层目录。

举例1:

<!-- 当前目录中的图片 -->
<img src="1.jpg">
<img src="./1.jpg">

<!-- 上一级目录中的图片 -->
<img src="../1.jpg">

相对路径不会出现这种情况:

<img src="aaa/../bbb/1.jpg">

../ 要么不写,要么就写在开头。

举例2:

<img src="images/1.png">

上方代码的意思是说,当前html页面有一个并列的文件夹 images ,在文件夹 images 中存放了一张图片 1.png

效果:

相对路径的面试题。现有如下文件层级图:

问题:如果想在index.html中插入1.png,那么对应的img语句是?

分析:

现在document是最大的文件夹,里面有两个文件夹work和photo。work中又有一个文件夹叫做myweb。myweb文件夹里面有 index.html。 所以index.html在myweb文件夹里面,上一级就是work文件夹,上两级就是document文件夹。通过document文件夹当做一个中转站,进入photo文件夹,看到了1.png

答案:

<img src="../../photo/1.png" />

写法二:图片的绝对路径

绝对路径包括以下两种:

1. 以盘符开始的绝对路径。举例:

<img src="C:\Users\alu\OneDrive\文档\yydnas test\images\1.png">

2. 网络路径。举例:

<img src="https://www.xxx.com/images/1.png">

相对路径和绝对路径的总结

相对路径的好处:站点不管拷贝到哪里,文件和图片的相对路径关系都是不变的。相对路径使用有一个前提,就是网页文件和你的图片,必须在一个服务器上。

总结一下

无论是在 a 标签还是 img 标签上,如果要用路径。只有两种路径能用,就是相对路径和绝对路径:

  • 相对路径从自己出发,找到别人。

  • 绝对路径,就是 http:// 或者 https:// 开头的路径。

img标签的其他属性

width、height 属性

  • width:图像的宽度。

  • height:图像的高度。

width和height,在 HTML5 中的单位是 CSS 像素,在 HTML 4 中既可以是像素,也可以是百分比。可以只指定 width 和 height 中的一个值,浏览器会根据原始图像进行缩放。

重要提示:如果要想保证图片等比例缩放,请只设置width和height中其中一个。

Alt 属性

  • alt:当图片不可用(无法显示)的时候,代替图片显示的内容。alt是英语 alternate “替代”的意思,代表替换资源。

Alt属性效果演示:

如上图所示:当图片 src 不可用的时候,显示文字。这样做,至少能让用户知道,这个图片大概是什么内容。

title 属性

  • title提示性文本。鼠标悬停时出现的文本。

title 属性不该被用作一幅图片在 alt 之外的补充说明信息。如果一幅图片需要小标题,使用 figure 或 figcaption 元素。

title 元素的值一般作为提示条(tooltip)呈现给用户,在光标于图片上停下后显示出来。尽管这确实能给用户提供更多的信息,您不该假定用户真的能看到:用户可能只有键盘或触摸屏。如果要把特别重要的信息提供给用户,可以选择上面提供的一种方法将其内联显示,而不是使用 title。

举例:

<img src="images/1.png" title="网站图片">

效果:

align 属性

  • 图片的align属性:图片和周围文字的相对位置。属性取值可以是:bottom(默认)、center、top、left、right。

如果想实现图文混排的效果,请使用align属性,取值为left或right。

我们来分别看一下这align属性的这几个属性值的区别。

  1. align="",图片和文字底端对齐。即默认情况下的显示效果:

  1. align="center":图片和文字水平方向上居中对齐。显示效果:

  1. align="top":图片与文字顶端对齐。显示效果:

  1. align="left":图片在文字的左边。显示效果:

  1. align="right":图片在文字的右边。显示效果:

其他已废弃的属性

  • Align(已废弃):指图片的水平对齐方式,属性值可以是:top、middle、bottom、left、center、right。该属性已废弃,替换为 vertical-align这个CSS属性。

  • border(已废弃):给图片加边框,单位是像素,边框的颜色默认黑色。该属性已废弃,替换为 border这个CSS属性。

  • Hspace(已废弃):指图片左右的边距。

  • Vspace(已废弃):指图片上下的边距。

HTML:04.图片标签最先出现在Forever Young

]]>
https://www.luxiyue.com/learning/html%ef%bc%9a04-%e5%9b%be%e7%89%87%e6%a0%87%e7%ad%be/feed/ 0