本质上CSS计数器是由CSS维护的变量,这些变量可能根据CSS规则增加以跟踪使用次数。这允许你根据文档位置来调整内容表现。 CSS计数器是CSS2.1中自动计数编号部分的实现。
计数器的值通过使用counter-resetcounter-increment 操作,在 content 上应用 counter()counters()函数来显示在页面上。

counter-reset

counter-reset属性含有一列一个或多个计数器,每个后面可以跟一个可选的整数。该整数给定了每次出现该元素时给计数器设置的值,默认为0。

counter-reset 简单的来说就是使用css计数器时重置该值。例如:

1
2
3
4
5
6
7
8
9
10
11
12
/* 此时item就是css维护的计数器的变量,每次遇见class中含有title的元素就会重置item,由于后面未跟数字,所以重置为默认值0 */
.title {
counter-reset: item;
}
/* 此时item1就是css维护的计数器的变量,每次遇见class中含有title1的元素就会重置item1,item1后面跟数字1,所以将item1重置为1 */
.title1 {
counter-reset: item1 1;
}
/* 此时item2、item3就是css维护的计数器的变量,每次遇见class中含有title2的元素就会重置item2、item3,item2后面跟数字2,所以将item2重置为2,item3后面跟数字3,所以将item3重置为3 */
.title2 {
counter-reset: item2 2 item3 3;
}

counter-increment

counter-increment属性接受一个或多个计数器名(标识符),每个后面都可以跟一个可选的整数。这个整数表示每次出现该元素时计数器递增几。默认增量是1,可以接受正整数、0和负整数。

counter-increment 简单来说就是定义递增量。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
/* 此时item就是css维护的计数器的变量,每次遇见class中含有title的元素就会在item的基础上递增其后设置的数字,由于后面未跟数字,所以递增量为默认值0 */
.title li:before {
counter-increment: item;
content: counter(item);
}
/* 此时item1就是css维护的计数器的变量,每次遇见class中含有title1的元素就会在item1的基础上递增其后设置的数字1 */
.title1 {
counter-reset: item1 1;
}
/* 此时item2就是css维护的计数器的变量,每次遇见class中含有title2的元素会在item2的基础上递增其后设置的数字2,然后再递增3 */
.title2 {
counter-reset: item2 2 item2 3;
}

关键字’none’,’inherit’和’initial’不能用作计数器名。值为’none’表示不需要重置或者递增计数器。

本文摘自:http://www.ayqy.net/doc/css2-1/generate.html#counters

本文转自:https://www.w3ctech.com/topic/112

现代浏览器中获取实际宽度和高度

现代浏览器(包括IE9)为IMG元素提供了naturalWidthnaturalHeight属性来获取实际宽度与高度 ,代码如下:

1
2
3
var 
nWidth = document.getElementById('example').naturalWidth,
nHeight = document.getElementById('example').naturalHeight;

在IE7,8中获取实际宽度和高度

在IE8及以前浏览器中并不支持naturalWidthnaturalHeight属性。为IE7,8采用new Image()的方式来获取widthheight

1
2
3
4
5
6
7
8
9
10
function getNatural (DOMelement) {
var img = new Image();
img.src = DOMelement.src;
return {width: img.width, height: img.height};
}

var
natural = getNatural(document.getElementById('example')),
nWidth = natural.width,
nHeight = natural.height;

jQuery naturalWidth() and naturalHeight()

为jQuery添加了两个方法:naturalWidth()naturalHeight()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
(function($){
var
props = ['Width', 'Height'],
prop;

while (prop = props.pop()) {
(function (natural, prop) {
$.fn[natural] = (natural in new Image()) ?
function () {
return this[0][natural];
} :
function () {
var
node = this[0],
img,
value;

if (node.tagName.toLowerCase() === 'img') {
img = new Image();
img.src = node.src,
value = img[prop];
}
return value;
};
}('natural' + prop, prop.toLowerCase()));
}
}(jQuery));

// 如何使用:
var
nWidth = $('img#example').naturalWidth(),
nHeight = $('img#example').naturalHeight();

关于input输入框fixed在窗口底部的时候,input获取焦点,弹出输入法,input会被输入法遮挡,导致输入内容不方便。

我们可以用scrollIntoViewscrollIntoViewIfNeeded来解决这个问题。scrollIntoViewscrollIntoViewIfNeeded都是让当前的元素滚动到浏览器窗口的可视区域内。关于scrollIntoViewscrollIntoViewIfNeeded 的具体信息可以查看 此处

在MDN的 scrollIntoView 中有下面一段话:

取决于其它元素的布局情况,此元素可能不会完全滚动到顶端或底端。

所以应用scrollIntoView 的时候并不一定会滚动到顶端和底端。

解决input被遮挡的问题可以先点击此处查看 例子 ,或者直接用手机扫描二维码:
input被遮挡问题的处理例子

从例子中可以看到,每次点击input输入框之后,输入法会优先弹出,300ms之后将input输入框滚动到浏览器窗口的可视区域内,输入内容之后,点击确定,会在内容区域新增刚刚输入的内容,并且在300ms之后将它滚动到浏览器窗口的可视区域内。

亲测在安卓和ios下的微信6.6.7版本均有效。

例子代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
<!DOCTYPE html>
<html>

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>scrollIntoView</title>
<link rel="stylesheet" href="https://fxss5201.cn/project/css/normalize.css">
<style>
html,
body {
height: 100%;
font-family: "Microsoft YaHei", Arial, Helvetica, "宋体", sans-serif;
font-size: 14px;
user-select: none;
-webkit-touch-callout: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
.clearfix:before,
.clearfix:after {
content: '.';
display: block;
width: 0;
height: 0;
overflow: hidden;
visibility: hidden;
font-size: 0;
line-height: 0;
}
.clearfix:after {
clear: both;
}
.clearfix {
zoom: 1;
}
.header {
position: fixed;
left: 0;
top: 0;
z-index: 10;
width: 100%;
height: 50px;
line-height: 50px;
padding: 0 15px;
box-sizing: border-box;
color: #fff;
background: #999;
}
.body {
padding: 50px 15px;
width: 100%;
overflow-y: scroll;
box-sizing: border-box;
line-height: 30px;
}
.footer {
position: fixed;
left: 0;
bottom: 0;
z-index: 10;
width: 100%;
height: 50px;
padding: 8px 15px 9px;
box-sizing: border-box;
background: #fff;
border-top: 1px solid #ddd;
}
.sure-btn {
padding: 0;
float: right;
margin-left: 10px;
width: 50px;
height: 32px;
color: #fff;
font-size: 14px;
background: #0FAEFF;
border: 0;
border-radius: 3px;
-webkit-appearance: none;
}
.ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: normal;
}
.text-input {
box-sizing: border-box;
width: 100%;
height: 32px;
border-radius: 3px;
padding: 0 6px;
border: 1px solid #ddd;
-webkit-appearance: none;
}
</style>
</head>

<body>
<div class="header">header</div>
<div class="body" id="body">
body</br>
body</br>
body</br>
body</br>
body</br>
body</br>
body</br>
body</br>
body</br>
body</br>
body</br>
body</br>
body</br>
body</br>
body</br>
body</br>
body</br>
body</br>
body</br>
body</br>
body</br>
body</br>
body</br>
body</br>
</div>
<div class="footer" id="footer">
<button class="sure-btn" id="sureBtn">确定</button>
<div class="ellipsis">
<input type="text" class="text-input" id="textInput">
</div>
</div>
<script src="https://fxss5201.cn/project/js/jquery-1.11.3.js"></script>
<script>
$(function () {
$("#textInput").on("focus", function () {
setTimeout(function () {
$("#textInput")[0].scrollIntoView();
$("#textInput")[0].scrollIntoViewIfNeeded();
}, 300);
});

$("#sureBtn").on("click", function () {
var textInputValur = $.trim($("#textInput").val());
$("#textInput").val("").focus();
var body = $("#body");
if (!textInputValur) {
return false;
}
var str = $('<span>' + textInputValur + '</span></br>');
body.append(str);
setTimeout(function () {
str[0].scrollIntoView();
str[0].scrollIntoViewIfNeeded();
}, 300);
})
})
</script>
</body>

</html>

本文转自:scrollIntoView 与 scrollIntoViewIfNeeded API 介绍

根据 MDN 的描述,Element.scrollIntoView()方法让当前的元素滚动到浏览器窗口的可视区域内。而Element.scrollIntoViewIfNeeded()方法也是用来将不在浏览器窗口的可见区域内的元素滚动到浏览器窗口的可见区域。但如果该元素已经在浏览器窗口的可见区域内,则不会发生滚动。此方法是标准的Element.scrollIntoView()方法的专有变体。

因而再有什么回到顶部、去到置顶位置和键盘弹出挡住输入框之类的需求,都可以简单解决了。

然而,面对好用的 API,前端们第一个反映都是,看兼容性!

可以直接点击此处查看

先看scrollIntoView的:
scrollIntoView

看到一片黄黄绿绿的,基本可以安心,不支持的只是某个属性的取值而已,下面会有介绍~

之后看看scrollIntoViewIfNeeded
scrollIntoViewIfNeeded

IEFireFox全红,如果PC端想用的话,基本只能内部项目了,略为可惜。但移动端还是绿悠悠的,基本都OK,可以安心使用~

由于本文是介绍向~因而每个属性我都写了点小demo,点进去就可以体验一下哦!

scrollIntoView

先介绍scrollIntoView,使用起来其实很简单,获取某个元素后,直接调用scrollIntoView()即可,简单的 demo 点这就好,点一下侧边的小绿块,页面就会滚上去。demo代码大概长这样:

1
2
3
4
5
6
7
8
9
10
11
<body>
<div class="chunk"></div>
<div class="btn">click</div>
<script>
const btn = document.querySelector('.btn');
const test = document.querySelector('.chunk');
btn.addEventListener('click', function() {
test.scrollIntoView();
})
</script>
</body>

是不是很简单~不过可能有同学就有疑问了,这不就和锚点定位一样吗?感觉毫无意义啊!先别急,当你调用scrollIntoView的时候,其实是可以传参数进去的。scrollIntoView只接受一个参数,但接受两种类型的参数,分别是Boolean型参数和Object型参数。
先说Boolean型参数,顾名思义,参数可以使truefalse。如果为true,元素的顶端将和其所在滚动区的可视区域的顶端对齐。若为false,元素的底端将和其所在滚动区的可视区域的底端对齐。简单的 例子 可以点这里。主要代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<body>
<div class="chunk"></div>
<div class="btn-top">up</div>
<div class="btn-bottom">down</div>
<script>
const up = document.querySelector('.btn-top');
const down = document.querySelector('.btn-bottom');
const test = document.querySelector('.chunk');
up.addEventListener('click', function() {
test.scrollIntoView(true);
});
down.addEventListener('click', function() {
test.scrollIntoView(false);
});
</script>
</body>

如你所见到的,当传入参数为分别为truefalse时,当点击右侧的按钮时,红色的div会贴近可视区域的顶部或底部。

之后是Object型参数,这个对象有两个选项,也就是对象里面的keyblock与之前的Boolean型参数一致,不过值不再是truefalse,是更语义化的startend

另一个选项是behavior,MDN上给出三个可取的值,分别是autoinstantsmooth。这个选项决定页面是如何滚动的,实测autoinstant都是瞬间跳到相应的位置,查阅W3C后发现了这么一句:

The instant value of scroll-behavior was renamed to auto.

因而基本可以确定两者表现是一致的。而smooth就是有动画的过程,可惜的是之前提及兼容性时说过,黄色其实不支持某个属性,就是不支持behavior取值为smooth。而且,实测了IE及移动端的UC浏览器后发现,它们根本就不支持Object型参数,因而在调用scrollIntoView({...})时,只有默认的结果,即scrollIntoView(true)。简单的 例子 看这里,如果想体验smooth的效果,需要使用Chrome或者Firefox哦!主要代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<body>
<div class="chunk"></div>
<div class="btn-top">up</div>
<div class="btn-bottom">down</div>
<script>
const up = document.querySelector('.btn-top');
const down = document.querySelector('.btn-bottom');
const test = document.querySelector('.chunk');
up.addEventListener('click', function() {
test.scrollIntoView({
block: 'start',
behavior: 'smooth'
});
});
down.addEventListener('click', function() {
test.scrollIntoView({
block: 'end',
behavior: 'smooth'
});
});
</script>
</body>

scrollIntoViewIfNeeded

介绍完scrollIntoView,是时候介绍一下它的变体scrollIntoViewIfNeeded了。两者主要区别有两个。首先是scrollIntoViewIfNeeded是比较懒散的,如果元素在可视区域,那么调用它的时候,页面是不会发生滚动的。其次是scrollIntoViewIfNeeded只有Boolean型参数,也就是说,都是瞬间滚动,没有动画的可能了。

scrollIntoViewIfNeeded可以接受一个Boolean型参数,和scrollIntoView不同,true为默认值,但不是滚动到顶部,而是让元素在可视区域中居中对齐;false时元素可能顶部或底部对齐,视乎元素靠哪边更近。简单的 例子 可以点这里。大致代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<body>
<div class="chunk"></div>
<div class="scrollIntoView">scrollIntoView top</div>
<div class="scrollIntoViewIfNeeded-top">scrollIntoViewIfNeeded top</div>
<div class="scrollIntoViewIfNeeded-bottom">scrollIntoViewIfNeeded botom</div>
<script>
const scrollIntoView = document.querySelector('.scrollIntoView');
const scrollIntoViewIfNeededTop = document.querySelector('.scrollIntoViewIfNeeded-top');
const scrollIntoViewIfNeededBottom = document.querySelector('.scrollIntoViewIfNeeded-bottom');
const test = document.querySelector('.chunk');
scrollIntoView.addEventListener('click', function() {
test.scrollIntoView(true);
});
scrollIntoViewIfNeededTop.addEventListener('click', function() {
test.scrollIntoViewIfNeeded(true);
});
scrollIntoViewIfNeededBottom.addEventListener('click', function() {
test.scrollIntoViewIfNeeded(false);
});
</script>
</body>

如文档所说,当红色的div完全在可视区域的情况下,调用scrollIntoView()是会发生滚动,而调用scrollIntoViewIfNeeded()则不会。而我实践后发现了一些文档没有的细节。当元素处于可视区域,但不是全部可见的情况下,调用scrollIntoViewIfNeeded()时,无论参数是true还是false,都会发生滚动,而且效果是滚动到元素与可视区域顶部或底部对齐,视乎元素离哪端更近。这个大家需要注意一下~

前段时间写了一个canvas应用——将方形图片处理为圆形 ,最近就想把这个完善一下,所以就再补充一个canvas的圆角矩形处理方式。

例子

你可以直接点击此处查看 例子 ,先一睹为快。

参数

参数 默认值 描述
img null 图片(img)对象
type 0,number类型 设置生成图片的大小:0设置生成的图片大小是以图片设置的css大小为准,1设置生成的图片大小是以图片分辨率为准
radius 0,number类型 圆角矩形的圆角半径

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/**
* 把图片处理成圆角矩形
* @param {object} img 图片(img)对象
* @param {number} type 设置生成图片的大小:0设置生成的图片大小是以图片设置的css大小为准,1设置生成的图片大小是以图片分辨率为准,默认值为0
* @param {number} radius 圆角矩形的半径,默认值为0
* @return {string} return base64 png图片字符串
*/
function circleRect_image(option) {
var img = option.img;
var type = option.type || 0;
var radius = option.radius || 0;
var imgSize, canvas, ctx;
if (type){
imgSize = {
width: img.naturalWidth,
height: img.naturalHeight
}
}else{
imgSize = {
width: img.width,
height: img.height
}
}
canvas = document.createElement('canvas');
if (!canvas.getContext) { // 判断浏览器是否支持canvas,如果不支持在此处做相应的提示
console.log('您的浏览器版本过低,暂不支持。');
return false;
}
canvas.width = imgSize.width;
canvas.height = imgSize.height;
ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, imgSize.width, imgSize.height);
ctx.save();
ctx.beginPath();
roundedRect(ctx, 0, 0, imgSize.width, imgSize.height, radius);
ctx.clip(); // 通过裁剪得到圆角矩形
if(type){
ctx.drawImage(img, 0, 0, imgSize.width, imgSize.height, 0, 0, imgSize.width, imgSize.height);
}else{
ctx.drawImage(img, 0, 0, img.naturalWidth, img.naturalHeight, 0, 0, imgSize.width, imgSize.height);
}
ctx.restore();

// 画圆角矩形
function roundedRect(ctx, x, y, width, height, radius) {
ctx.strokeStyle = "#fff";
ctx.beginPath();
ctx.moveTo(x, y + radius);
ctx.lineTo(x, y + height - radius);
ctx.quadraticCurveTo(x, y + height, x + radius, y + height);
ctx.lineTo(x + width - radius, y + height);
ctx.quadraticCurveTo(x + width, y + height, x + width, y + height - radius);
ctx.lineTo(x + width, y + radius);
ctx.quadraticCurveTo(x + width, y, x + width - radius, y);
ctx.lineTo(x + radius, y);
ctx.quadraticCurveTo(x, y, x, y + radius);
ctx.stroke();
}
return canvas.toDataURL('image/png');
}