Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
壓縮。
我是沒(méi)想到還是有人會(huì)說(shuō),沒(méi)有基礎(chǔ)的人才會(huì)問(wèn)html空格的問(wèn)題,這些細(xì)節(jié)沒(méi)有什么用,而我這里給大家簡(jiǎn)單的匯報(bào)一下。
首先第一個(gè)問(wèn)題,標(biāo)簽和標(biāo)簽之間空格的問(wèn)題。先看一下這個(gè)家伙,這個(gè)例子,這兩種寫(xiě)法有什么區(qū)別?直接看這里的例子。第一種寫(xiě)法包含了一個(gè)奇怪的空格,但是第二種寫(xiě)法是不包含空格的。
這個(gè)東西在html里面,它的解析,它的Dome節(jié)點(diǎn)中看是看不出來(lái)的,而我們看它們的表現(xiàn)完全一致的,要怎么去理解?畢竟寫(xiě)的代碼不是所有的都會(huì)去掛工程畫(huà),這個(gè)地方是animate和note的區(qū)別,它們的內(nèi)存結(jié)構(gòu)是不一樣的。
比如第一個(gè)節(jié)點(diǎn),它下面包含了5個(gè)字節(jié)點(diǎn),有3個(gè)是文本節(jié)點(diǎn)。再看第二個(gè)節(jié)點(diǎn),這個(gè)節(jié)點(diǎn)下面只有兩個(gè)節(jié)點(diǎn),只有兩個(gè)span的標(biāo)簽。去看html的時(shí)候,它的表現(xiàn)是字符,標(biāo)簽是字符的一種結(jié)構(gòu),但是最終使用的時(shí)候是document,它是節(jié)點(diǎn),中間是有轉(zhuǎn)換的,這是理論。
這里聊的就是text文本節(jié)點(diǎn),而對(duì)于文本節(jié)點(diǎn),那里面的東西就非常惡心了,東西就特別多了。比如現(xiàn)在就要這三個(gè)字,無(wú)壓縮它的寬度,要怎么去計(jì)算?找一下無(wú)壓縮節(jié)點(diǎn),找的是無(wú)壓縮里面文案的節(jié)點(diǎn),它是沒(méi)有寬度的,上面可以看到它的寬度是144,這是它渲染出來(lái)的,它的寬度是沒(méi)有的,這個(gè)節(jié)點(diǎn)里面是不給提供它的寬高的,這是很惡心的一件事情。
必須得基于容器,基于它外側(cè)的容器,來(lái)去獲取到它最終的寬度,計(jì)算中文的寬度是多少,大家有見(jiàn)過(guò)這樣的需求吧。
再說(shuō)一個(gè),現(xiàn)在要節(jié)點(diǎn)信息的位置,比如這里做了個(gè)例子,現(xiàn)在要定義文案的偏移量,要怎么去計(jì)算?當(dāng)用第一種方式里面寫(xiě)的有SPA標(biāo)簽以后,直接獲取標(biāo)簽,用行內(nèi)的標(biāo)簽來(lái)去進(jìn)行獲取,里面包含了左邊定位的信息,三百八十七。
·但現(xiàn)在要計(jì)算第二個(gè)節(jié)點(diǎn),它的問(wèn)題跟剛才的問(wèn)題是一樣的,如何去獲取到text的節(jié)點(diǎn)?它的寬高獲取不到的,沒(méi)有偏移量的信息,得進(jìn)行特殊的計(jì)算,這就是其中一個(gè)比較大的區(qū)別,這個(gè)東西就比較操蛋了。
·再來(lái)一個(gè)跨局跟行內(nèi)元素的規(guī)則,規(guī)則包含哪些?標(biāo)準(zhǔn)的規(guī)則是所有的子元素,塊菊元素當(dāng)中所有的子元素要么都是塊菊,要么都是內(nèi)聯(lián)的。看一下它們兩個(gè)這種寫(xiě)法上有沒(méi)有區(qū)別?這兩種寫(xiě)法是沒(méi)有任何區(qū)別的,因?yàn)樗强鐦O,它是內(nèi)聯(lián)的,而內(nèi)聯(lián)和跨極是不允許進(jìn)行交叉使用的。
它的寫(xiě)法相當(dāng)于它的外層又包含了一個(gè)隱匿的跨句元素,直接看頁(yè)面中表現(xiàn)的效果,它倆的表現(xiàn)效果是一致的,雖然標(biāo)簽不一樣,但是最終展示的結(jié)果是一樣的,它倆的表現(xiàn)形式是一樣的。
如果這個(gè)邏輯知道,再解釋一下下面這種寫(xiě)法,這兩種寫(xiě)法是一樣的,解釋一下為什么?已知div是跨距元素,跨距元素當(dāng)中里面所有的節(jié)點(diǎn)全部都是跨距元素或者是行內(nèi)元素,而又知道空格會(huì)轉(zhuǎn)換成text的節(jié)點(diǎn),而Tech的節(jié)點(diǎn)是行內(nèi)元素,所以它的外層又會(huì)包成一行隱匿的節(jié)點(diǎn),它是div,所以這里包含div,這里又包含div,有3個(gè)空格。
塊級(jí):所有的子元素都是塊,中間兩偏差的兩個(gè)一,這兩個(gè)元素它倆的表現(xiàn)是一樣的,可以看到它最終表現(xiàn)的效果。
這里引出的額外的概念就是塌陷,沒(méi)有內(nèi)容,沒(méi)有div它的content是0,它的高度必須得是0,否則這種實(shí)現(xiàn)就會(huì)跟理解是有差異的,而這種實(shí)現(xiàn)又會(huì)產(chǎn)生一些額外的其他的問(wèn)題。
舉一個(gè)例子,往from表單里面,往table里面插入元素,恰巧那一行的數(shù)據(jù)它就是為空,后端返回這個(gè)空詞無(wú)串,這個(gè)時(shí)候要不要進(jìn)行特殊處理?比如圖中這個(gè)table,這個(gè)table它就是沒(méi)有數(shù)據(jù),這兩行就是沒(méi)有數(shù)據(jù),最終展示的時(shí)候可能就是第一行它是正常的,它的高度可能是40,第二行第三行它就是癟了,發(fā)現(xiàn)了因?yàn)闆](méi)有內(nèi)容產(chǎn)生的原因。
要怎么去解決這個(gè)問(wèn)題?phone表格也是一樣的,它也會(huì)有類似的問(wèn)題。當(dāng)然還會(huì)有一些其他的比較惡心的要求,現(xiàn)在是復(fù)文本,現(xiàn)在是編輯代碼,而要求內(nèi)容跟寫(xiě)的結(jié)構(gòu)一樣,現(xiàn)在要再怎么去處理第三類?使用PRE標(biāo)簽,刷新一下,空殼這個(gè)問(wèn)題又得到了一個(gè)處理。
這里就涉及到了具體的解析結(jié)構(gòu)、規(guī)則,而這些問(wèn)題聊完以后又可以回到上一個(gè)問(wèn)題,HM中有哪些標(biāo)簽?關(guān)于如何分類的?標(biāo)簽的分類其實(shí)按功能分、按和模型去區(qū)分,沒(méi)問(wèn)題都沒(méi)問(wèn)題,但至少所有的類型得加上。
比如hider meter,它們是行類的還是塊兒級(jí)?包括直播的時(shí)候彈幕上已經(jīng)提到過(guò)行內(nèi)塊級(jí),有些內(nèi)容是說(shuō)錯(cuò)的,講道理當(dāng)時(shí)就是聽(tīng)個(gè)響,因?yàn)榇鸢柑胀恕?梢园凑樟硗獾囊环N結(jié)構(gòu)來(lái)去區(qū)分,可以基于轉(zhuǎn)換后的元素進(jìn)行區(qū)分,而它包含很多。
·第一種:空元素,沒(méi)有內(nèi)容的元素,它的核心是什么?現(xiàn)在寫(xiě)一個(gè)image標(biāo)簽,里面的標(biāo)簽內(nèi)容不要那樣寫(xiě),非要這樣去寫(xiě),里面加一個(gè)奇怪的標(biāo)簽內(nèi)容,肯定是標(biāo)加不進(jìn)去的,是沒(méi)有辦法放到image里面的。包括heart,包括這些里面的其他的標(biāo)簽全部都是這樣的,最終會(huì)做一些特殊的操作來(lái)去處理里面的span或者里面文案的內(nèi)容。
·第二個(gè)元素,模板元素。它是用來(lái)定義下面模板用的,是比較特殊的,里面的內(nèi)容不會(huì)進(jìn)行額外的解析。比如現(xiàn)在寫(xiě)了一個(gè)奇怪的標(biāo)簽,里面加了一個(gè)script,這個(gè)時(shí)候刷起甲會(huì)怎樣?刷新一下標(biāo)簽會(huì)進(jìn)行執(zhí)行。當(dāng)然是如果用time play就不會(huì)進(jìn)行執(zhí)行,它是一個(gè)元素的,是一個(gè)模板類的標(biāo)簽,刷新一下不會(huì)進(jìn)行執(zhí)行。
·第三類,原始文本元素。這類元素其實(shí)往下看,主要是看這兩個(gè)元素包含可轉(zhuǎn)移和不可轉(zhuǎn)移,一般是兩個(gè),提示器寫(xiě)的也行,一般是兩個(gè)。這兩個(gè)會(huì)進(jìn)行解析,需要其他的解析器來(lái)對(duì)里面的代碼去進(jìn)行解析。但是textl里邊放的這些元素是不會(huì)進(jìn)行解析的。
比如現(xiàn)在把tablet改成taxl,大家注意里面的節(jié)點(diǎn)會(huì)怎么處理?會(huì)去執(zhí)行嗎?不會(huì)執(zhí)行,并且會(huì)把里面的內(nèi)容放到里面的內(nèi)容,這個(gè)東西也是以前代替template的核心原因。去看一些比較老的實(shí)現(xiàn)的時(shí)候,比如百度中里面會(huì)用一些taxl代替template,因?yàn)橐郧皼](méi)這個(gè)元素。
·第五個(gè),這兩原始文本算兩個(gè),第五個(gè)就是外來(lái)元素,這里寫(xiě)的又比較清楚,非HTML規(guī)范的一些元素。特殊的一些元素,外來(lái)的不是html里面規(guī)范的。
最后就是普通元素,打鼓本身就是筆試題的平替,但是它的內(nèi)容跟筆試是不一樣的,筆試是有標(biāo)準(zhǔn)答案的,是要打分的,60分以后繼續(xù)聊,沒(méi)有超過(guò)60分就可以走了。
但打鼓不是,拋出一個(gè)問(wèn)題,永遠(yuǎn)是論述題,大家來(lái)相互的溝通,有可能面試官的這個(gè)點(diǎn)不會(huì)沒(méi)關(guān)系,完全可以主動(dòng)地去提。面試官我覺(jué)得這個(gè)點(diǎn)不重要,我更了解瀏覽器中編語(yǔ)原理的部分,了解瀏覽器中關(guān)于渲染引擎的這一部分,可以基于這個(gè)問(wèn)題來(lái)探討一下關(guān)于節(jié)點(diǎn),關(guān)于剛才這些問(wèn)題到底是有一個(gè)什么樣的答案,這是沒(méi)有問(wèn)題的。
反正一句話,我是不認(rèn)可沒(méi)有技術(shù)的人才會(huì)問(wèn)hmr空格問(wèn)題的,更不認(rèn)可這些細(xì)節(jié)問(wèn)題沒(méi)有任何用的言論。
. autoescape
控制當(dāng)前自動(dòng)轉(zhuǎn)義的行為,有on和off兩個(gè)選項(xiàng)
{% autoescape on %}
{{ body }}
{% endautoescape %}
2. block
定義一個(gè)子模板可以覆蓋的塊
3. comment
注釋,{% comment %} 和 {% endcomment %}之間的內(nèi)容被解釋為注釋
4. crsf_token
一個(gè)防止CSRF攻擊(跨站點(diǎn)請(qǐng)求偽造)的標(biāo)簽
5. cycle
循環(huán)給出的字符串或者變量,可以混用
{% for o in some_list %} <tr class="{% cycle 'row1' rowvalue2 'row3' %}"> ... </tr>{% endfor %}
值得注意的是,這里的變量的值默認(rèn)不是自動(dòng)轉(zhuǎn)義的,要么你相信你的變量,要么你就是用強(qiáng)制轉(zhuǎn)義的方法,
{% for o in some_list %} <tr class="{% filter force_escape %}{% cycle rowvalue1 rowvalue2 %}{% endfilter %}"> ... </tr>{% endfor %}
在某些情況下,你可能想循環(huán)外部引用循環(huán)的下一個(gè)值,這時(shí)你需要用as給cycle標(biāo)簽一個(gè)名字,這個(gè)名字代表的是當(dāng)前循環(huán)的值,但你可以在cycle標(biāo)簽里面是用這個(gè)變量來(lái)獲得循環(huán)的下一個(gè)值
<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>
渲染的結(jié)果是
<tr> <td class="row1">...</td> <td class="row1">...</td></tr><tr> <td class="row2">...</td> <td class="row2">...</td></tr>
但是cycle標(biāo)簽一旦定義,默認(rèn)就會(huì)用循環(huán)的第一個(gè)值,當(dāng)你僅僅是想定義一個(gè)循環(huán),而不想打印循環(huán)的值的時(shí)候(比如你在父模板定義變量以方便繼承),你可以是用cycle的silent參數(shù)(必須保證silent是cycle的最后一個(gè)參數(shù),并且silent也具有繼承的特點(diǎn),盡管第二行的cycle沒(méi)有silent參數(shù),但由于rowcoclors是前面定義的且包含silent參數(shù)的,第二個(gè)cycle也具有silent 循環(huán)的特點(diǎn)
{% cycle 'row1' 'row2' as rowcolors silent %} {% cycle rowcolors %}
6. debug
輸出所有的調(diào)試信息,包括當(dāng)前上下文和導(dǎo)入的模塊
7. extends
表示說(shuō)當(dāng)前模板繼承了一個(gè)父模板
接受一個(gè)包含父模板名字的變量或者字符串常量
8. filter
通過(guò)可用的過(guò)濾器過(guò)濾內(nèi)容,過(guò)濾器之間還可以相互(調(diào)用)
{% filter force_escape|lower %} This text will be HTML-escaped, and will appear in all lowercase. {% endfilter %}
9. firstof
返回列表中第一個(gè)可用(非False)的變量或者字符串,注意的是firstof中的變量非自動(dòng)轉(zhuǎn)義
{% firstof var1 var2 var3 "fallback value" %}
10. for
for循環(huán),可以在后面加入reversed參數(shù)遍歷逆序的列表
{% for obj in list reversed %
你還可以根據(jù)列表的數(shù)據(jù)來(lái)寫(xiě)for語(yǔ)句,例如對(duì)于字典類型的數(shù)據(jù)
{% for key, value in data.items %} {{ key }}: {{ value }} {% endfor %}
for循環(huán)還有一系列有用的變量
變量 | 描述 |
---|---|
forloop.counter | 當(dāng)前循環(huán)的索引,從1開(kāi)始 |
forloop.counter0 | 當(dāng)前循環(huán)的索引,從0開(kāi)始 |
forloop.revcounter | 當(dāng)前循環(huán)的索引(從后面算起),從1開(kāi)始 |
forloop.revcounter0 | 當(dāng)前循環(huán)的索引(從后面算起),從0開(kāi)始 |
forloop.first | 如果這是第一次循環(huán)返回真 |
forloop.last | 如果這是最后一次循環(huán)返回真 |
forloop.parentloop | 如果是嵌套循環(huán),指的是外一層循環(huán) |
11. for...empty
如果for循環(huán)的參數(shù)-列表為空,將執(zhí)行empty里面的內(nèi)容
<ul>{% for athlete in athlete_list %} <li>{{ athlete.name }}</li>{% empty %} <li>Sorry, no athlete in this list!</li>{% endfor %}<ul>
12. if
條件語(yǔ)句
{% 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標(biāo)簽里面可以使用and,or和not三個(gè)布爾操作符
==,!=,<,>,<=,>=,in,not in等操作符
這些操作符就不一一詳細(xì)說(shuō)了,一目了然
在if標(biāo)簽里面,這些操作符可以做成復(fù)雜的表達(dá)式
13. ifchange
檢測(cè)一個(gè)值在循環(huán)的最后有沒(méi)有改變
所以這個(gè)標(biāo)簽實(shí)在循環(huán)里面是用的,有兩個(gè)用法:
沒(méi)有接受參數(shù)時(shí),比較的是ifchange標(biāo)簽里面的內(nèi)容相比以前是否有變化,有變化時(shí)生效
接受一個(gè)或以上各參數(shù)的時(shí)候,如果有一個(gè)或者以上的參數(shù)發(fā)生變化時(shí),有變化時(shí)生效
ifchange可以有else標(biāo)簽
{% for match in matches %} <div style="background-color: {% ifchanged match.ballot_id %} {% cycle "red" "blue" %} {% else %} grey {% endifchanged %} ">{{ match }}</div>{% endfor %}
13. ifequal
僅當(dāng)兩個(gè)參數(shù)相等的時(shí)候輸出塊的內(nèi)容,可以配合else輸出
{% ifequal user.username "adrian" %} ... {% endifequal %}
14. ifnotequal
跟ifequal類似
15. include
加載一個(gè)模板并用當(dāng)前上下文(include該模板的模板的上下文)渲染它,接受一個(gè)變量或者字符串參數(shù)
當(dāng)然你也可以在include的時(shí)候傳遞一些參數(shù)進(jìn)來(lái)
{% include "name_snippet.html" with person="Jane" greeting="Hello" %}
如果你只想接受傳遞的參數(shù),不接受當(dāng)前模板的上下文時(shí),你可以是用only參數(shù)
{% include "name_snippet.html" with greeting="Hi" only %}
16. load
加載一個(gè)自定義的模板標(biāo)簽集合,見(jiàn)單獨(dú)的一節(jié)講解
17. now
顯示當(dāng)前的時(shí)間日期,接受格式化字符串的參數(shù)
It is {% now "jS F Y H:i" %}
參數(shù)有已經(jīng)定義好的一些參考參數(shù): DATE_FORMAT(月日年), DATETIME_FORMAT(月日年時(shí)),SHORT_DATE_FORMAT(月/日/年) or SHORT_DATETIME_FORMAT(月/日/年/時(shí))
18. regroup
通過(guò)共同的屬性對(duì)一個(gè)列表的相似對(duì)象重新分組,加入你有一個(gè)城市(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'}, ]
你想按照國(guó)家country這個(gè)屬性來(lái)重新分組已得到下面的結(jié)果,那么你可以這么做
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并不會(huì)重新排序,所以,請(qǐng)確保city在regroup之前已經(jīng)按country排好序,否則將得不到你預(yù)期想要的結(jié)果,如果不確定可以用dictsort過(guò)濾器排序
{% regroup cities|dictsort:"country" by country as country_list %}
19. spaceless
移除html標(biāo)簽之間的空格,注意是標(biāo)簽之間的空格,標(biāo)簽與內(nèi)容之間的空格不會(huì)被刪除
{% spaceless %} <p> <a href="foo/">Foo</a> </p>{% endspaceless %}
結(jié)果是
<p><a href="foo/">Foo</a></p>
20. ssi
在頁(yè)面上輸出給定文件的內(nèi)容
{% ssi /home/html/ljworld.com/includes/right_generic.html %}
使用parsed參數(shù)可以使得輸入的內(nèi)容可以作為一個(gè)模板從而可以使用當(dāng)前模板的上下文
{% ssi /home/html/ljworld.com/includes/right_generic.html parsed %}
21. url
返回一個(gè)絕對(duì)路徑的引用(沒(méi)有域名的url),接受的第一個(gè)參數(shù)是一個(gè)視圖函數(shù)的名字,然后從urls配置文件里面找到那個(gè)視圖函數(shù)對(duì)應(yīng)的url,
22. widthratio
這個(gè)標(biāo)簽計(jì)算給定值與最大值的比率,然后把這個(gè)比率與一個(gè)常數(shù)相乘,返回最終的結(jié)果
<img src="bar.gif" height="10" width="{% widthratio this_value max_value 100 %}" />
23. with
用更簡(jiǎn)單的變量名緩存復(fù)雜的變量名
{% with total=business.employees.count %} {{ total }} employee{{ total|pluralize }} {% endwith %}
盡管初衷是這樣,但你不必都是如此,哈哈
擊右上方紅色按鈕關(guān)注“小鄭搞碼事”,每天都能學(xué)到知識(shí),搞懂一個(gè)問(wèn)題!
由于HTML代碼的空格通常會(huì)被瀏覽器忽略,所以我們很有必要對(duì)瀏覽器處理空格的一些規(guī)則有個(gè)詳細(xì)的認(rèn)識(shí),這樣我們后面才能詳述它的解決辦法。
效果是這樣的:
由此可此可以知道瀏覽器的默認(rèn)處理規(guī)則一:文字的前后空格都會(huì)忽略,內(nèi)部連續(xù)空格只有自作一個(gè)。
原樣輸出可能是我們這樣寫(xiě)代碼的本意,要讓這段代碼原樣輸出的方法有兩個(gè)(使用標(biāo)簽/使用表示空格的實(shí)體代碼):
方法一:<pre><span class="space"> 小鄭 搞碼 </span></pre>
方法二:<span class="space"> 小鄭 搞碼 </span>
關(guān)于規(guī)則部分還有一點(diǎn),來(lái)看一段代碼:
效果是:
表示,瀏覽器對(duì)字符的處理不僅限于空格,還有制表符(\t),換行符(\r和\n)。
同樣讓這段代碼換行可能是我們寫(xiě)的本意,讓這段代碼換行的方法有兩個(gè):
方法一:套一個(gè)pre標(biāo)簽
方法二:<span class="space">小鄭<br/>搞碼</span>
最后總結(jié)一下:
HTML語(yǔ)言的空格處理,基本上就是直接過(guò)濾。這樣的處理過(guò)于粗糙,完全忽視了原始文本內(nèi)部的空格可能是有意義的。所以CSS提供了一個(gè)屬性white-space屬性來(lái)靈活控制空格。下篇詳述。
*請(qǐng)認(rèn)真填寫(xiě)需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。