整合营销服务商

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

免费咨询热线:

没有技术的人才会问空格问题--? #web前端

没有技术的人才会问空格问题??? #web前端

压缩。

我是没想到还是有人会说,没有基础的人才会问html空格的问题,这些细节没有什么用,而我这里给大家简单的汇报一下。

首先第一个问题,标签和标签之间空格的问题。先看一下这个家伙,这个例子,这两种写法有什么区别?直接看这里的例子。第一种写法包含了一个奇怪的空格,但是第二种写法是不包含空格的。

这个东西在html里面,它的解析,它的Dome节点中看是看不出来的,而我们看它们的表现完全一致的,要怎么去理解?毕竟写的代码不是所有的都会去挂工程画,这个地方是animate和note的区别,它们的内存结构是不一样的。

比如第一个节点,它下面包含了5个字节点,有3个是文本节点。再看第二个节点,这个节点下面只有两个节点,只有两个span的标签。去看html的时候,它的表现是字符,标签是字符的一种结构,但是最终使用的时候是document,它是节点,中间是有转换的,这是理论。

这里聊的就是text文本节点,而对于文本节点,那里面的东西就非常恶心了,东西就特别多了。比如现在就要这三个字,无压缩它的宽度,要怎么去计算?找一下无压缩节点,找的是无压缩里面文案的节点,它是没有宽度的,上面可以看到它的宽度是144,这是它渲染出来的,它的宽度是没有的,这个节点里面是不给提供它的宽高的,这是很恶心的一件事情。

必须得基于容器,基于它外侧的容器,来去获取到它最终的宽度,计算中文的宽度是多少,大家有见过这样的需求吧。

再说一个,现在要节点信息的位置,比如这里做了个例子,现在要定义文案的偏移量,要怎么去计算?当用第一种方式里面写的有SPA标签以后,直接获取标签,用行内的标签来去进行获取,里面包含了左边定位的信息,三百八十七。

·但现在要计算第二个节点,它的问题跟刚才的问题是一样的,如何去获取到text的节点?它的宽高获取不到的,没有偏移量的信息,得进行特殊的计算,这就是其中一个比较大的区别,这个东西就比较操蛋了。

·再来一个跨局跟行内元素的规则,规则包含哪些?标准的规则是所有的子元素,块菊元素当中所有的子元素要么都是块菊,要么都是内联的。看一下它们两个这种写法上有没有区别?这两种写法是没有任何区别的,因为它是跨极,它是内联的,而内联和跨极是不允许进行交叉使用的。

它的写法相当于它的外层又包含了一个隐匿的跨句元素,直接看页面中表现的效果,它俩的表现效果是一致的,虽然标签不一样,但是最终展示的结果是一样的,它俩的表现形式是一样的。

如果这个逻辑知道,再解释一下下面这种写法,这两种写法是一样的,解释一下为什么?已知div是跨距元素,跨距元素当中里面所有的节点全部都是跨距元素或者是行内元素,而又知道空格会转换成text的节点,而Tech的节点是行内元素,所以它的外层又会包成一行隐匿的节点,它是div,所以这里包含div,这里又包含div,有3个空格。

块级:所有的子元素都是块,中间两偏差的两个一,这两个元素它俩的表现是一样的,可以看到它最终表现的效果。

这里引出的额外的概念就是塌陷,没有内容,没有div它的content是0,它的高度必须得是0,否则这种实现就会跟理解是有差异的,而这种实现又会产生一些额外的其他的问题。

举一个例子,往from表单里面,往table里面插入元素,恰巧那一行的数据它就是为空,后端返回这个空词无串,这个时候要不要进行特殊处理?比如图中这个table,这个table它就是没有数据,这两行就是没有数据,最终展示的时候可能就是第一行它是正常的,它的高度可能是40,第二行第三行它就是瘪了,发现了因为没有内容产生的原因。

要怎么去解决这个问题?phone表格也是一样的,它也会有类似的问题。当然还会有一些其他的比较恶心的要求,现在是复文本,现在是编辑代码,而要求内容跟写的结构一样,现在要再怎么去处理第三类?使用PRE标签,刷新一下,空壳这个问题又得到了一个处理。

这里就涉及到了具体的解析结构、规则,而这些问题聊完以后又可以回到上一个问题,HM中有哪些标签?关于如何分类的?标签的分类其实按功能分、按和模型去区分,没问题都没问题,但至少所有的类型得加上。

比如hider meter,它们是行类的还是块儿级?包括直播的时候弹幕上已经提到过行内块级,有些内容是说错的,讲道理当时就是听个响,因为答案太普通了。可以按照另外的一种结构来去区分,可以基于转换后的元素进行区分,而它包含很多。

·第一种:空元素,没有内容的元素,它的核心是什么?现在写一个image标签,里面的标签内容不要那样写,非要这样去写,里面加一个奇怪的标签内容,肯定是标加不进去的,是没有办法放到image里面的。包括heart,包括这些里面的其他的标签全部都是这样的,最终会做一些特殊的操作来去处理里面的span或者里面文案的内容。

·第二个元素,模板元素。它是用来定义下面模板用的,是比较特殊的,里面的内容不会进行额外的解析。比如现在写了一个奇怪的标签,里面加了一个script,这个时候刷起甲会怎样?刷新一下标签会进行执行。当然是如果用time play就不会进行执行,它是一个元素的,是一个模板类的标签,刷新一下不会进行执行。

·第三类,原始文本元素。这类元素其实往下看,主要是看这两个元素包含可转移和不可转移,一般是两个,提示器写的也行,一般是两个。这两个会进行解析,需要其他的解析器来对里面的代码去进行解析。但是textl里边放的这些元素是不会进行解析的。

比如现在把tablet改成taxl,大家注意里面的节点会怎么处理?会去执行吗?不会执行,并且会把里面的内容放到里面的内容,这个东西也是以前代替template的核心原因。去看一些比较老的实现的时候,比如百度中里面会用一些taxl代替template,因为以前没这个元素。

·第五个,这两原始文本算两个,第五个就是外来元素,这里写的又比较清楚,非HTML规范的一些元素。特殊的一些元素,外来的不是html里面规范的。

最后就是普通元素,打鼓本身就是笔试题的平替,但是它的内容跟笔试是不一样的,笔试是有标准答案的,是要打分的,60分以后继续聊,没有超过60分就可以走了。

但打鼓不是,抛出一个问题,永远是论述题,大家来相互的沟通,有可能面试官的这个点不会没关系,完全可以主动地去提。面试官我觉得这个点不重要,我更了解浏览器中编语原理的部分,了解浏览器中关于渲染引擎的这一部分,可以基于这个问题来探讨一下关于节点,关于刚才这些问题到底是有一个什么样的答案,这是没有问题的。

反正一句话,我是不认可没有技术的人才会问hmr空格问题的,更不认可这些细节问题没有任何用的言论。

. autoescape

控制当前自动转义的行为,有on和off两个选项

{% autoescape on %}

{{ body }}

{% endautoescape %}

2. block

定义一个子模板可以覆盖的块

3. comment

注释,{% comment %} 和 {% endcomment %}之间的内容被解释为注释

4. crsf_token

一个防止CSRF攻击(跨站点请求伪造)的标签

5. cycle

循环给出的字符串或者变量,可以混用

{% for o in some_list %} <tr class="{% cycle 'row1' rowvalue2 'row3' %}">
 ... </tr>{% endfor %}

值得注意的是,这里的变量的值默认不是自动转义的,要么你相信你的变量,要么你就是用强制转义的方法,

{% for o in some_list %} <tr class="{% filter force_escape %}{% cycle rowvalue1 rowvalue2 %}{% endfilter %}">
 ... </tr>{% endfor %}

在某些情况下,你可能想循环外部引用循环的下一个值,这时你需要用as给cycle标签一个名字,这个名字代表的是当前循环的值,但你可以在cycle标签里面是用这个变量来获得循环的下一个值

<tr>
<td class="{% cycle 'row1' 'row2' as rowcolors %}">...</td>
<td class="{{ rowcolors }}">...</td></tr><tr>
<td class="{% cycle rowcolors %}">...</td>
<td class="{{ rowcolors }}">...</td></tr>

渲染的结果是

<tr>
<td class="row1">...</td>
<td class="row1">...</td></tr><tr>
<td class="row2">...</td>
<td class="row2">...</td></tr>

但是cycle标签一旦定义,默认就会用循环的第一个值,当你仅仅是想定义一个循环,而不想打印循环的值的时候(比如你在父模板定义变量以方便继承),你可以是用cycle的silent参数(必须保证silent是cycle的最后一个参数,并且silent也具有继承的特点,尽管第二行的cycle没有silent参数,但由于rowcoclors是前面定义的且包含silent参数的,第二个cycle也具有silent 循环的特点

{% cycle 'row1' 'row2' as rowcolors silent %}
{% cycle rowcolors %}

6. debug

输出所有的调试信息,包括当前上下文和导入的模块

7. extends

表示说当前模板继承了一个父模板

接受一个包含父模板名字的变量或者字符串常量

8. filter

通过可用的过滤器过滤内容,过滤器之间还可以相互(调用)

{% filter force_escape|lower %}
 This text will be HTML-escaped, and will appear in all lowercase.
{% endfilter %}

9. firstof

返回列表中第一个可用(非False)的变量或者字符串,注意的是firstof中的变量非自动转义

{% firstof var1 var2 var3 "fallback value" %}

10. for

for循环,可以在后面加入reversed参数遍历逆序的列表

{% for obj in list reversed %

你还可以根据列表的数据来写for语句,例如对于字典类型的数据

{% for key, value in data.items %}
 {{ key }}: {{ value }}
{% endfor %}

for循环还有一系列有用的变量

变量 描述
forloop.counter当前循环的索引,从1开始
forloop.counter0当前循环的索引,从0开始
forloop.revcounter当前循环的索引(从后面算起),从1开始
forloop.revcounter0当前循环的索引(从后面算起),从0开始
forloop.first如果这是第一次循环返回真
forloop.last如果这是最后一次循环返回真
forloop.parentloop如果是嵌套循环,指的是外一层循环

11. for...empty

如果for循环的参数-列表为空,将执行empty里面的内容

<ul>{% for athlete in athlete_list %} <li>{{ athlete.name }}</li>{% empty %} <li>Sorry, no athlete in this list!</li>{% endfor %}<ul>

12. if

条件语句

{% if athlete_list %}
 Number of athletes: {{ athlete_list|length }}
{% elif athlete_in_locker_room_list %}
 Athletes should be out of the locker room soon!
{% else %}
 No athletes.
{% endif %}

布尔操作符

在if标签里面可以使用and,or和not三个布尔操作符

==,!=,<,>,<=,>=,in,not in等操作符

这些操作符就不一一详细说了,一目了然

在if标签里面,这些操作符可以做成复杂的表达式

13. ifchange

检测一个值在循环的最后有没有改变

所以这个标签实在循环里面是用的,有两个用法:

  • 没有接受参数时,比较的是ifchange标签里面的内容相比以前是否有变化,有变化时生效

  • 接受一个或以上各参数的时候,如果有一个或者以上的参数发生变化时,有变化时生效

ifchange可以有else标签

{% for match in matches %} <div style="background-color:
 {% ifchanged match.ballot_id %}
 {% cycle "red" "blue" %}
 {% else %}
 grey
 {% endifchanged %}
 ">{{ match }}</div>{% endfor %}

13. ifequal

仅当两个参数相等的时候输出块的内容,可以配合else输出

{% ifequal user.username "adrian" %}
 ...
{% endifequal %}

14. ifnotequal

跟ifequal类似

15. include

加载一个模板并用当前上下文(include该模板的模板的上下文)渲染它,接受一个变量或者字符串参数

当然你也可以在include的时候传递一些参数进来

{% include "name_snippet.html" with person="Jane" greeting="Hello" %}

如果你只想接受传递的参数,不接受当前模板的上下文时,你可以是用only参数

{% include "name_snippet.html" with greeting="Hi" only %}

16. load

加载一个自定义的模板标签集合,见单独的一节讲解

17. now

显示当前的时间日期,接受格式化字符串的参数

It is {% now "jS F Y H:i" %}

参数有已经定义好的一些参考参数: DATE_FORMAT(月日年), DATETIME_FORMAT(月日年时),SHORT_DATE_FORMAT(月/日/年) or SHORT_DATETIME_FORMAT(月/日/年/时)

18. regroup

通过共同的属性对一个列表的相似对象重新分组,加入你有一个城市(city)的列表如下

cities=[
 {'name': 'Mumbai', 'population': '19,000,000', 'country': 'India'},
 {'name': 'Calcutta', 'population': '15,000,000', 'country': 'India'},
 {'name': 'New York', 'population': '20,000,000', 'country': 'USA'},
 {'name': 'Chicago', 'population': '7,000,000', 'country': 'USA'},
 {'name': 'Tokyo', 'population': '33,000,000', 'country': 'Japan'},
]

你想按照国家country这个属性来重新分组已得到下面的结果,那么你可以这么做

  • Mumbai: 19,000,000

  • Calcutta: 15,000,000

  • India

  • New York: 20,000,000

  • Chicago: 7,000,000

  • USA

  • Tokyo: 33,000,000

  • Japan

{% regroup cities by country as country_list %}<ul>{% for country in country_list %} <li>{{ country.grouper }} <ul>
 {% for item in country.list %} <li>{{ item.name }}: {{ item.population }}</li>
 {% endfor %} </ul>
 </li>{% endfor %}</ul>

值得注意的是,regroup并不会重新排序,所以,请确保city在regroup之前已经按country排好序,否则将得不到你预期想要的结果,如果不确定可以用dictsort过滤器排序

{% regroup cities|dictsort:"country" by country as country_list %}

19. spaceless

移除html标签之间的空格,注意是标签之间的空格,标签与内容之间的空格不会被删除

{% spaceless %} <p>
 <a href="foo/">Foo</a>
 </p>{% endspaceless %}

结果是

<p><a href="foo/">Foo</a></p>

20. ssi

在页面上输出给定文件的内容

{% ssi /home/html/ljworld.com/includes/right_generic.html %}

使用parsed参数可以使得输入的内容可以作为一个模板从而可以使用当前模板的上下文

{% ssi /home/html/ljworld.com/includes/right_generic.html parsed %}

21. url

返回一个绝对路径的引用(没有域名的url),接受的第一个参数是一个视图函数的名字,然后从urls配置文件里面找到那个视图函数对应的url,

22. widthratio

这个标签计算给定值与最大值的比率,然后把这个比率与一个常数相乘,返回最终的结果

<img src="bar.gif" height="10" width="{% widthratio this_value max_value 100 %}" />

23. with

用更简单的变量名缓存复杂的变量名

{% with total=business.employees.count %}
 {{ total }} employee{{ total|pluralize }}
{% endwith %}

尽管初衷是这样,但你不必都是如此,哈哈

击右上方红色按钮关注“小郑搞码事”,每天都能学到知识,搞懂一个问题!

由于HTML代码的空格通常会被浏览器忽略,所以我们很有必要对浏览器处理空格的一些规则有个详细的认识,这样我们后面才能详述它的解决办法。

一、默认规则

效果是这样的:

由此可此可以知道浏览器的默认处理规则一:文字的前后空格都会忽略,内部连续空格只有自作一个。

原样输出可能是我们这样写代码的本意,要让这段代码原样输出的方法有两个(使用标签/使用表示空格的实体代码):

方法一:<pre><span class="space"> 小郑 搞码 </span></pre>

方法二:<span class="space"> 小郑 搞码 </span>

二、另一个规则

关于规则部分还有一点,来看一段代码:

效果是:

表示,浏览器对字符的处理不仅限于空格,还有制表符(\t),换行符(\r和\n)。

同样让这段代码换行可能是我们写的本意,让这段代码换行的方法有两个:

方法一:套一个pre标签

方法二:<span class="space">小郑<br/>搞码</span>

最后总结一下:

HTML语言的空格处理,基本上就是直接过滤。这样的处理过于粗糙,完全忽视了原始文本内部的空格可能是有意义的。所以CSS提供了一个属性white-space属性来灵活控制空格。下篇详述。