整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

link vs @import:CSS 引入方式大PK,谁才是你的最佳选择?

Web 开发的浩瀚海洋中,CSS 犹如点睛之笔,为网页增光添彩。而引入 CSS 样式的方式,也决定了网页渲染的效率和代码的可维护性。 link 和 @import 作为两种常见的 CSS 引入方式,今天就来一场正面对决,看看谁才是你的最佳选择!

Round 1:身份揭秘,从出身说起

  • link :HTML 的正牌标签,身兼多职,不仅能引入 CSS,还能定义 RSS、rel 链接属性等。可谓是 HTML 家族中的“多面手”。
  • @import :CSS 语法规则的忠实守护者,专注于导入样式表,是 CSS 世界的“专业选手”。

Round 2:速度之争,加载顺序大比拼

  • link :与 HTML 标签并肩作战,页面加载时同步加载,赢在起跑线。
  • @import : 姗姗来迟,页面加载完毕后才开始加载,容易造成页面闪烁,用户体验稍逊一筹。

Round 3:兼容性考验,谁更胜一筹?

  • link : HTML 元老级标签,不存在兼容性问题,稳如泰山。
  • @import :CSS2.1 语法,存在一定的兼容性问题,在老旧浏览器中可能会出现样式加载失败的情况。

Round 4:控制权争夺,DOM 操作谁更强?

  • link : 受 JavaScript 和 DOM 的绝对控制,可以通过修改 link 标签属性动态改变样式,灵活多变。
  • @import :游离于 DOM 之外,无法通过 JavaScript 直接控制,显得有些“高冷”。

Round 5:权重较量,谁的影响力更大?

  • link :在样式层叠中拥有更高的权重,其定义的样式会覆盖 @import 引入的样式。

终极 PK:示例代码大 showdown

<!DOCTYPE html>
<html>
<head>
  <title>link vs @import</title>
  <link rel="stylesheet" href="style.css"> 
</head>
<body>
  <h1>Hello world</h1>
</body>
</html>
/* style.css */
@import url("other-style.css");

源码解析

在浏览器解析 HTML 文件时,会依次解析 link 标签和 style 标签,并下载相应的 CSS 文件。@import 规则会在 CSS 文件解析时被执行,浏览器会再次发送请求下载 other-style.css 文件。

总结:link更胜一筹

综上所述,link 标签凭借其加载速度快、兼容性好、可控性强等优势,在 CSS 引入方式的较量中更胜一筹,是大多数场景下的最佳选择。

当然,@import 也并非一无是处,在某些特殊情况下,它也能发挥作用。例如,当我们需要根据不同的条件加载不同的样式表时,可以使用 @import 结合 JavaScript 实现动态加载。

#头条创作挑战赛#

lt;input type="file">

在HTML中,通过 <input type="file> 标签可以让用户从其设备中选择一个或多个文件,并将文件提交到服务器或通过JS操作文件。在MDN文档中了解更多。

<label for="avatar">Choose a profile picture:</label>
<input type="file"
id="avatar" name="avatar"
accept="image/png, image/jpeg">

指定文件格式

使用accept属性可以指定文件选择的格式,例如只选择word文件,则accept=".doc,.docx,application/msword"。

<input
  type="file"
  id="docpicker"
  accept=".doc,.docx,application/msword" />

然而,这种指定并不是绝对的,用户可以在系统文件选择框中切换成"*",从而选择其他文件格式。

单选/多选

默认情况下,文件选择是单选的。通过multiple属性可以指定多选。

<input
  type="file"
  id="docpicker"
  multiple="true"
  accept=".doc,.docx,application/msword" />

使用JS获取文件

获取 <input type="file> 的DOM实例,通过HTMLInputElement.files来获取选择的文件。

<div>
  <label for="file">选择要上传的文件</label>
  <input type="file" id="file" name="file" multiple />
</div>

<script>
var inputEl = document.getElementById('file');
inputEl.addEventListener('change', () => {
  console.log(inputEl.files);
});
</script>

HTMLInputElement.files中的file元素包含:namelastModifiedsizetype等信息。

封装文件选择功能

通常情况下,为了美观,我们不会仅使用原生的<input type="file>标签来实现文件选择功能。我们可以使用CSS对样式进行修改,或者通过其他方式实现点击其他元素来触发隐藏的<input>来选择文件。这种方式会比较繁琐,而引入组件库会增加复杂度。我们可以创建一个文件选择函数,它可以直接完成文件选择操作,而不必关心样式。 通过JS创建HTMLInputElement,并将其type属性设置为file,然后触发点击事件来选择文件。在创建<input>实例后,不要将其挂载到DOM上,以避免出现在页面中。最后,添加change监听器到<input>实例中,在回调函数中获取选中的文件。由于文件选择是一个异步事件,因此使用Promise来处理选择的文件。

export const selectFile = (accepts = ['*'], multiple = false) => {
  // 创建<input>标签
  const inputElem = document.createElement('input');
  // 设置属性`type`为`file`
  inputElem.setAttribute('type', 'file');
  // 设置属性`visibility`为`hidden`
  inputElem.setAttribute('visibility', 'hidden');

  if (Array.isArray(accepts) && accepts.length > 0) {
    // 设置文件格式
    inputElem.setAttribute('accept', accepts.join(','));
  }

  if (multiple) {
    // 设置多选文件
    inputElem.setAttribute('multiple', 'true');
  }

  // 主动触发点击事件
  inputElem.click();

  return new Promise((resolve, reject) => {
    // 在实例上添加监听
    inputElem.addEventListener('change', () => {
      if (!inputElem.files || inputElem.files?.length == 0) {
        reject();
      } else {
        const files = Array.from(inputElem.files);
        // 主要防止用户主动选择了非指定的文件格式
        if (illegalFiles(files)) {
          reject();
        }
        resolve(files);
      }
    });
  });

  function illegalFiles(files) {
    return !accepts.includes('*') && files.some((file) => !accepts.includes(`.${getFileExtension(file)}`));
  }
};

以下是selectFile函数的使用示例:

// 单选文件
selectFile(['.jpg', '.png'])
.then((files) => {
	console.log(files);
	// 处理文件
})
.catch(() => {
	console.log('选择文件出错');
});

// 多选文件
selectFile(['.jpg', '.png'], true)
.then((files) => {
	console.log(files);
	// 处理文件
})
.catch(() => {
	console.log('选择文件出错');
});

上述示例中,第一个selectFile函数调用将只允许选择 .jpg和 .png格式的单个文件,而第二个调用将允许选择 .jpg和 .png格式的多个文件。在选择文件之后,可以使用then回调处理返回的文件数组。如果选择文件时出现错误,则将会调用catch回调函数。

完整封装

封装的文件选择函数在用户没有选择文件时,点击【确定】按钮时调用者会决策失败。但是如果用户主动点击系统的文件选择框里的【取消选择】按钮,此时并不会触发inputElement的change事件,导致调用方无法识别。 虽然DOM没有提供监听【取消选择】的API,但是可以通过监听window对象的focus事件,再加上inputElement.files来判断用户是否点击了【取消选择】按钮。具体实现方式为,在调用selectFile函数前先监听window对象的focus事件,当事件触发时判断inputElement.files是否为空,如果为空则表示用户点击了【取消选择】按钮。需要注意的是,这种方法只能监听浏览器失焦事件,对于一些特殊情况可能无法生效。

export class BaseError extends Error {
  cause?: Error;

  constructor(message: string, options?: ErrorOptions) {
    super(message, options);
    this.name = this.constructor.name;
  }
}

export class FileSelectCancelError extends BaseError {
  constructor() {
    super('Cancel select');
  }
}

export class IllegalFileError extends BaseError {
  accepts: string[];

  constructor(accepts: string[]) {
    super(`Please select files in ${accepts} format`);
    this.accepts = accepts;
  }
}

export const selectFile = (accepts = ['*'], multiple = false) => {
  // 创建<input>标签
  const inputElem = document.createElement('input');
  // 设置属性`type`为`file`
  inputElem.setAttribute('type', 'file');
  // 设置属性`visibility`为`hidden`
  inputElem.setAttribute('visibility', 'hidden');

  if (Array.isArray(accepts) && accepts.length > 0) {
    // 设置文件格式
    inputElem.setAttribute('accept', accepts.join(','));
  }

  if (multiple) {
    // 设置多选文件
    inputElem.setAttribute('multiple', 'true');
  }

  // 主动触发点击事件
  inputElem.click();

  return new Promise((resolve, reject) => {
    window.addEventListener(
      'focus',
      () => {
        // 这里必须异步处理`inputElement`
        setTimeout(() => {
          if (!inputElement.files || inputElement.files?.length === 0) {
            reject(new FileSelectCancelError());
          }
        }, 1000);
      },
      { once: true }
    );
    inputElement.addEventListener('change', () => {
      if (!inputElement.files || inputElement.files?.length === 0) {
        reject(new FileSelectCancelError());
      } else {
        const files = Array.from(inputElement.files);
        if (illegalFiles(files)) {
          reject(new IllegalFileError(accepts));
        }
        resolve(files);
      }
    });
  });

  function illegalFiles(files: File[]): boolean {
    return !accepts.includes('*') && files.some((file) => !accepts.includes(`.${getFileExtension(file)}`));
  }
};

以下是selectFile函数的使用示例:

const onFileSelect = async () => {
  try {
    const files = await selectFile(['jpg', 'png'], true);
    // 处理选择的文件
    console.log(files);
  } catch (error) {
    if (error instanceof FileSelectCancelError) {
      console.log('取消选择文件');
    } else if (error instanceof IllegalFileError) {
      console.log(`只能选择 ${error.accepts} 格式的文件`);
    } else {
      console.error(error);
    }
  }
};

// 触发文件选择
onFileSelect();

在上面的示例中,selectFile函数会返回一个 Promise 对象,用于异步获取用户选择的文件。如果用户选择了文件,则 Promise 对象会被解析,返回选择的文件数组;如果用户取消选择,则 Promise 对象会被拒绝,返回一个 FileSelectCancelError 对象;如果用户选择了不合法的文件格式,则 Promise 对象也会被拒绝,返回一个 IllegalFileError 对象。在使用 selectFile 函数时,可以使用 try-catch 语句来捕捉 Promise 对象的解析和拒绝结果,并进行相应的处理。

欢迎大家留言评论!

txt文件变成html网页文件

如果您看过《HTML是什么?——零基础自学网页制作》这篇教程,请按照其中说明创建一个txt文件。具体过程如下:

step1:在您方便的磁盘中建立一个文件夹,命名为"零基础自学网页制作"。例如我在D盘中建立了"零基础自学网页制作"文件夹。

step2:在文件夹中创建"HTML框架.txt"文件。鼠标移动到空白处点击右键选择"文本文档"。

命名为"html框架",如下图所示。

如果您的电脑没有显示".txt"后缀的话,请做如下操作:点击"工具",找到"文件夹选项"

菜单如下:点击"查看选项"。

下拉滑条,找到"隐藏已知文件类型的扩展名"选项,将前面的对勾去掉。

如果您使用的是win10的话请参考《边学边做网页篇------初识HTML》,这也是我做的教程,不过以后都使用这个账号来发了。

step3:把"HTML框架"复制粘贴到"html框架.txt"文件中。HTML框架代码如下:

<!DOCTYPE HTML> <html> <head> </head><body> </body> </html>

代码讲解请参照《HTML是什么?——零基础自学网页制作》这篇教程中的讲解。

粘贴后效果如下:使用CTRL+s组合键保存文件。

step4:复制"html框架.txt"文件,更名为"第一个网页.txt"。原始的"html框架.txt"文件为以后备用。

如图所示:

step5:把"第一个网页.txt"的后缀名".txt"改为".html"。

首先将光标放在"第一个网页.txt"文件上,点击右键,选择"重命名"。如图:

选择".txt"

更改为".html",敲击回车键。这时会弹出一个对话框,如图:

大胆的点击"是"即可。

修改后文件是这样的,如图:因为我的默认浏览器是360,所以,".html"文件图标显示为360浏览器的图标,显示其他浏览器的图标也没有问题。

step6:将鼠标移动到"第一个网页.html"文件上,单击右键,选择打开方式,如图:

选择任何一个浏览器打开即可,我使用的是火狐浏览器(Firefox),打开后如图所示:空白一片。

点击键盘F12键,看一下控制台,如图:查看器中已经显示我们的代码框架了。成功!

如果网页是一道菜,那么,html框架我们可以理解为装菜的白盘子,所以我们打开框架时,浏览器显示一片白。下面我们为盘子中加些简单的"菜"。

为html页面添加标题与段落

首先我们为页面添加"标题"

在添加标题前,我们来看一下html框架代码中的内容,在<html></html>标签中有<head></head>和<body></body>两个兄弟标签。

我们在页面中看到的所有的内容都是添加到<body></body>标签中间!

<head></head>标签中的内容并不会显示在页面中。

那么如何添加"标题"呢?

标题在HTML中用<h></h>标签表示。在<h></h>中间加入文字内容即可。如下所示:

<h>第一个页面</h>

右键,使用"记事本"打开"第一个网页.html"文件。如图所示:如果您的"打开方式"中没有"记事本"请点击"选择默认程序"

在"其他程序"中找到"记事本"。点击"确定"。从此,"记事本"就一直存在于"打开方式"中了。

我们把这句代码粘贴到<body></body>之间。如下所示:保存后使用浏览器打开。

<!DOCTYPE HTML><html><head> </head> <body> <h>第一个页面</h> </body> </html>

然后,使用浏览器打开,如图所示:标题出现在页面中了。

下面,我们来添加段落内容。

段落在HTML中使用<p></p>标签添加。代码如下

<p>千里之行始于足下</p>

请各位自行将代码添加到"第一个网页.html"文件中吧!示例代码如下:

<!DOCTYPE HTML> <html> <head> </head> <body> <h>第一个网页</h><p>千里之行始于足下</p> </body> </html>

结果如图所示:

通过这个练习,我们可以发现一个规律,在<body></body>中,子元素代码的上下顺序代表了它在页面中显示的排版顺序。

这也简单回答了代码结构与排版的关系,html的标签语句只是标记了它所承载的信息的属性和版面位置。

基于这个特性,html被称为超文本标记语言。

下一期我们具体讨论页面中文字编辑的技巧。

喜欢的小伙伴请加关注,有任何问题请给我留言,欢迎大家给与指正!感激不尽!

HTML完整学习目录

HTML序章(学习目的、对象、基本概念)——零基础自学网页制作

HTML是什么?——零基础自学网页制作

HTML页面中head标签有啥用?——零基础自学网页制作

初识meta标签与SEO——零基础自学网页制作

HTML中的元素使用方法1——零基础自学网页制作

HTML中的元素使用方法2——零基础自学网页制作

HTML元素中的属性1——零基础自学网页制作

HTML元素中的属性2(路径详解)——零基础自学网页制作

使用HTML添加表格1(基本元素)——零基础自学网页制作

使用HTML添加表格2(表格头部与脚部)——零基础自学网页制作

使用HTML添加表格3(间距与颜色)——零基础自学网页制作

使用HTML添加表格4(行颜色与表格嵌套)——零基础自学网页制作

16进制颜色表示与RGB色彩模型——零基础自学网页制作

HTML中的块级元素与内联元素——零基础自学网页制作

初识HTML中的<div>块元素——零基础自学网页制作

在HTML页面中嵌入其他页面的方法——零基础自学网页制作

封闭在家学网页制作!为页面嵌入PDF文件——零基础自学网页制作

HTML表单元素初识1——零基础自学网页制作

HTML表单元素初识2——零基础自学网页制作

HTML表单3(下拉列表、多行文字输入)——零基础自学网页制作

HTML表单4(form的action、method属性)——零基础自学网页制作

HTML列表制作讲解——零基础自学网页制作

为HTML页面添加视频、音频的方法——零基础自学网页制作

音视频格式转换神器与html视频元素加字幕——零基础自学网页制作

HTML中使用<a>标签实现文本内链接——零基础自学网页制作