FrankKai.github.io icon indicating copy to clipboard operation
FrankKai.github.io copied to clipboard

一些低调的HTML属性

Open FrankKai opened this issue 6 years ago • 7 comments

  • <a>标签的download属性
  • <input>的accept属性
  • <img>的onerror属性
  • <div>的tabindex属性
  • <script>的async属性和defer属性
  • <link>的preload属性
  • <img>的fetchpriority属性

FrankKai avatar Jul 02 '18 06:07 FrankKai

<a>标签的download属性

这个属性可以叫浏览器下载一个URL,而不是导航,所以用户将被提示"下载一个本地文件"。如果属性有值,在Save提示时它将有一个预填充的文件名。(如果他们愿意用户可以改变文件名)。值没有严格限制,即使是/ 和 \也会被转换成下划线。大多数的文件系统对文件名做了一些限制,浏览器将根据具体情况做出调整。 注意: 这个属性紧仅仅用于same-origin URL。 尽管HTTP(s) URL需要在同源,blob: URLs 和data: URLs允许由js生成的内容,例如一个图片编辑器web应用中创建的图片,可以被下载。 如果HTTP报文头 Content-Disposition :提供与此属性不同的文件名,HTTP标头优先于此属性。 如果Content-Disposition:设置为inline时,Firefox优先考虑Content-Disposition,例如文件名大小写,Chrome优先考虑下载属性。

  • a标签download属性,从后往前匹配第一个.作为文件格式。 若是download='foobarbaz.bat.png',文件格式为.png;若是download='foobarbaz.bat',文件格式为.bat。
  • a标签的download属性值,若没有指明文件名,会以href中的文件格式进行匹配。 例如base64格式的data:image/png;,生成的文件格式为png格式。

使用download属性将<canvas>下载保存为png

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>a标签的download属性可以将canvas保存为png。</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
        * {
            margin: 0;
            padding: 0;
            font-family: sans-serif;
            background: #c0ffee
        }

        canvas {
            background: #fff;
        }

        a {
            background: #69c;
            color: #fff;
            padding: 5px 10px;
        }
    </style>
</head>

<body>
    <canvas></canvas>
    <script>
        // grab the canvas element, get the context for API access and 
        // preset some variables
        var canvas = document.querySelector('canvas'),
            c = canvas.getContext('2d'),
            mouseX = 0,
            mouseY = 0,
            width = 300,
            height = 300,
            colour = 'hotpink',
            mousedown = false;

        // resize the canvas
        canvas.width = width;
        canvas.height = height;

        function draw() {
            if (mousedown) {
                // set the colour
                c.fillStyle = colour;
                // start a path and paint a circle of 20 pixels at the mouse position
                c.beginPath();
                c.arc(mouseX, mouseY, 10, 0, Math.PI * 2, true);
                c.closePath();
                c.fill();
            }
        }

        // get the mouse position on the canvas (some browser trickery involved)
        canvas.addEventListener('mousemove', function (event) {
            if (event.offsetX) {
                mouseX = event.offsetX;
                mouseY = event.offsetY;
            } else {
                mouseX = event.pageX - event.target.offsetLeft;
                mouseY = event.pageY - event.target.offsetTop;
            }
            // call the draw function
            draw();
        }, false);

        canvas.addEventListener('mousedown', function (event) {
            mousedown = true;
        }, false);
        canvas.addEventListener('mouseup', function (event) {
            mousedown = false;
        }, false);

        var link = document.createElement('a');
        link.innerHTML = '下载图片';
        link.addEventListener('click', function (ev) {
            link.href = canvas.toDataURL();
            link.download = "a标签神奇的download属性.png";
        }, false);
        document.body.appendChild(link);

    </script>
</body>

</html>

FrankKai avatar Jul 02 '18 06:07 FrankKai

<input>的accept属性

accept 如果type属性为file,这个属性将服务器接收的文件类型。若type不是file,将被忽略。

"内容类型识别器"可以包含以下内容:

  • 停止符号"."加大小写敏感的文件名。例如:.pdf,.txt,.jpg,.png。
  • 没有任何插件的有效的MIME类型。
  • audio/* 代表sound files.
  • video/* 代表 video files.
  • image/* 代表 image files.

只允许上传类型为jpg,pdf格式的文件

<input type="file" accept=".jpg,.pdf" />

只允许上传类型为image的文件

<input type="file" accept="image/*" />

只允许上传类型为video类型的文件

<input type="file" accept="video/*" />

FrankKai avatar Jul 05 '18 04:07 FrankKai

<img>的onerror属性

可以用来处理src资源下载失败,显示很丑的碎裂图的情况。 image

  • 可以设置元素隐藏
<img :src="foo.bar.url" onerror="this.style.display = 'none'"/>
  • 可以设置默认图
<img :src="foo.bar.url" onerror="this.src = 'http://ov6jc8fwp.bkt.clouddn.com/D43AA1E7-29E9-4C1B-B615-7D4172907531.png'" />

FrankKai avatar Jul 07 '18 08:07 FrankKai

<div>的tabindex属性

  • tabindex属性代表着元素是否会被聚焦
  • tabindex属性也可以代表tab键导航的顺序
  • tabindex="-1"代表元素可以被聚焦,但是不能在tab键可访问的范围里,这对于构建无障碍的功能中很有用
  • tabindex="0"代表元素可以被聚焦,也可以在tab键可访问的范围里,访问顺序由DOM节点顺序决定
  • 尽量不要用大于0的tabindex,这可能会使得依赖辅助技术的人们无法操作页面
  • 如果为<div>也设置了tabindex,其子节点若没有设置tabindex,是无法使用ctrl/command+上/下/左/右进行scroll的。参考demo可以进行验证:https://jsfiddle.net/jainakshay/0b2q4Lgv/
  • tabindex的最大值是32767

在vue中的应用

解决在vue中为div绑定keyup事件失效的问题。

<div v-on:keyup.delete="keyupDeleteHandler" tabindex="-1"></div>

FrankKai avatar May 23 '19 06:05 FrankKai

<script>的async属性和defer属性

js文件的下载过程,会阻塞DOM解析,如果JavaScript文件中没有操作DOM的代码,就可以将JavaScript设为异步加载。

<script async type="text/javascript" src='foo.js'></script>
<script defer type="text/javascript" src='foo.js'></script>
  • async:脚本文件一旦加载完成,会立即执行,有可能阻塞
  • defer:脚本文件会在DOM解析完成后,不阻塞

相关问题

html解析过程中,script会阻塞html解析吗?为什么会阻塞?

会阻塞,因为script中的代码可能会操作DOM。

script标签的async和defer属性有什么区别?

defer不阻塞html解析,会在html解析后执行。async会在网络请求后立即执行,如果此时html仍然在解析,那么async会阻塞html解析

样式表是否会阻塞html解析?为什么?

样式表如果在script标签之前,会阻塞html解析。因为位于样式表之后的script,可能获取样式数据,如果不阻塞的话,获取时样式表可能没有加载完成,获取到错误的样式。

哪种方式可以保证最安全的DCL?

defer+样式表前置。defer保证脚本延迟加载,样式表前置保证样式加载完毕。

image

FrankKai avatar Feb 01 '21 06:02 FrankKai

<link>的preload属性

元素的rel属性的preload值允许您在HTML的中声明获取请求,指定您的页面将很快需要的资源,您希望在页面生命周期的早期,在浏览器的主要渲染机制启动之前开始加载。这可以确保它们更早可用,并且不太可能阻塞页面的呈现,从而提高性能。

  <link rel="preload" href="style.css" as="style">
  <link rel="preload" href="main.js" as="script">

通过as声明文件类型。

支持style,script,image,audio,video等等

FrankKai avatar Apr 24 '22 09:04 FrankKai

<img>fetchpriority属性

可以通过fetchpriority来控制资源优先级,不过截至2022年8月22日,这还是一个实验性api,兼容性不好。

例如:

  • 通过fetchpriority="high"提升主图的LCP速度
  • 通过fetchpriority="low"降低低优先级资源加载
  • iframe,fetch,script也都可以通过fetchpriority进行优先级控制

引自:https://addyosmani.com/blog/fetch-priority/

<!-- Increase the priority of this LCP hero image --> 
<img src="hero-image.jpg" fetchpriority="high" alt="Hero">

<!-- Decrease the priority for this above-the-fold image --> 
<img src="happy-cats.avif" fetchpriority="low" alt="Cat">

<!-- The third-party contents of this iframe load with a low priority --> 
<iframe src="https://youtu.be/JfVOS4VSpmA" fetchpriority="low"></iframe>

<script> 
// Trigger a fetch with low priority 
let suggestedContent = await fetch("/content/suggested", {priority: "low"}); 
</script>

// Scripts that are not critical can also be loaded with low-priority 
<script src="blocking_but_unimportant.js" fetchpriority="low"></script>
image

FrankKai avatar Aug 22 '22 02:08 FrankKai