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
、定義
<meta> 標(biāo)簽提供關(guān)于 HTML 文檔的元數(shù)據(jù)。它不會顯示在頁面上,但是對于機器是可讀的。可用于瀏覽器(如何顯示內(nèi)容或重新加載頁面),搜索引擎(關(guān)鍵詞),或其他 web 服務(wù)。
2、作用
meta里的數(shù)據(jù)是供機器解讀的,告訴機器該如何解析這個頁面,還有一個用途是可以添加服務(wù)器發(fā)送到瀏覽器的http頭部內(nèi)容,例如我們?yōu)轫撁嬷刑砑尤缦耺eta標(biāo)簽:
瀏覽器的頭部就會包括這些:
只有瀏覽器可以接受這些附加的頭部字段,并能以適當(dāng)?shù)姆绞绞褂盟鼈儠r,這些字段才有意義。
3、meta的必需屬性和可選屬性
meta的必需屬性是content,當(dāng)然并不是說meta標(biāo)簽里一定要有content,而是當(dāng)有http-equiv或name屬性的時候,一定要有content屬性對其進(jìn)行說明。例如:
必需屬性
<meta name="keywords" content="HTML,ASP,PHP,SQL">
這里面content里的屬性就是對keywords進(jìn)行的說明,所以呢也可以理解成一個鍵值對吧,就是{keywords:"HTML,ASP,PHP,SQL"}。
可選屬性
在W3school中,對于meta的可選屬性說到了三個,分別是http-equiv、name和scheme。考慮到scheme不是很常用,所以就只說下前兩個屬性吧。
http-equiv
http-equiv屬性是添加http頭部內(nèi)容,對一些自定義的,或者需要額外添加的http頭部內(nèi)容,需要發(fā)送到瀏覽器中,我們就可以是使用這個屬性。在上面的meta作用中也有簡單的說明,那么現(xiàn)在再舉個例子。例如我們不想使用js來重定向,用http頭部內(nèi)容控制,那么就可以這樣控制:
<meta http-equiv="Refresh" content="5;url=http://blog.yangchen123h.cn" />
在頁面中加入這個后,5秒鐘后就會跳轉(zhuǎn)到指定頁面啦,效果可看W3school的例子
name
第二個可選屬性是name,這個屬性是供瀏覽器進(jìn)行解析,對于一些瀏覽器兼容性問題,name屬性是最常用的,當(dāng)然有個前提就是瀏覽器能夠解析你寫進(jìn)去的name屬性才可以,不然就是沒有意義的。還是舉個例子吧:
<meta name="renderer" content="webkit">
這個meta標(biāo)簽的意思就是告訴瀏覽器,用webkit內(nèi)核進(jìn)行解析,當(dāng)然前提是瀏覽器有webkit內(nèi)核才可以,不然就是沒有意義的啦。當(dāng)然看到這個你可能會有疑問,這個renderer是從哪里冒出來的,我要怎么知道呢?這個就是在對應(yīng)的瀏覽器的開發(fā)文檔里就會有表明的,例如這個renderer是在360瀏覽器里說明的。360瀏覽器內(nèi)核控制Meta標(biāo)簽說明文檔
常用meta標(biāo)簽大總結(jié)
接下來就是常用的meta標(biāo)簽大總結(jié)啦,我會盡可能的做到全
charset
charset是聲明文檔使用的字符編碼,解決亂碼問題主要用的就是它,值得一提的是,這個charset一定要寫第一行,不然就可能會產(chǎn)生亂碼了。
charset有兩種寫法
兩個都是等效的。
百度禁止轉(zhuǎn)碼
百度會自動對網(wǎng)頁進(jìn)行轉(zhuǎn)碼,這個標(biāo)簽是禁止百度的自動轉(zhuǎn)碼
<meta http-equiv="Cache-Control" content="no-siteapp" />
SEO 優(yōu)化部分
viewport
viewport主要是影響移動端頁面布局的,例如:
content 參數(shù):
各瀏覽器平臺
Microsoft Internet Explorer
Google Chrome
360瀏覽器
UC手機瀏覽器
UCBrowser_U3_API
QQ手機瀏覽器
Apple iOS
Google Android
App Links
最后——移動端常用的meta
者:JavaScript
轉(zhuǎn)發(fā)鏈接:https://www.kancloud.cn/dennis/tgjavascript/241852
為 JavaScript 開發(fā)者,我們經(jīng)常忘記并不是所有人都像我們一樣了解 JavaScript,這被稱為知識的詛咒:當(dāng)我們精通某個內(nèi)容的時候,我們就不記得自己作為新人的時候有多么困惑。我們總是對其他人的能力估計過高,因此我們覺得,自己寫的類庫需要一些 JavaScript 代碼去初始化和配置也很正常。然而,一些用戶卻在使用過程中大費周折,他們瘋狂地從文檔中復(fù)制粘貼例子并隨機組合這些代碼,直到它們生效為止。
你或許會想:“所有寫 HTML 和 CSS 的人都會 JavaScript,對吧?”
你錯了。來看看我的調(diào)查結(jié)果吧,這是我所知道的唯一相關(guān)數(shù)據(jù)了。
根據(jù)投票結(jié)果來看,每兩個寫 HTML 和 CSS 的人中,就有一個對 JavaScript 沒有好感。 這是個值得讓人深思的數(shù)據(jù)結(jié)果。
舉個例子,以下的代碼用來初始化一個 jQuery UI 自動完成庫。
toml<div class="ui-widget">
<label for="tags">Tags: </label>
<input id="tags">
</div>
toml$( function() {
var availableTags = [
"ActionScript",
"AppleScript",
"Asp",
"BASIC",
"C"
];
$( "#tags" ).autocomplete({
source: availableTags
});
} );
你覺得這很簡單,甚至覺得即使那些根本不會 JavaScript 的人也會覺得簡單,對吧?
錯!非程序員在文檔中看到這個例子的時候,腦子里會閃過各種問題:“我該把這段代碼放哪兒呢?”“這些花括號、冒號和方括號都是什么意思?”“我要用這些嗎?”“如果我的元素沒有 ID 怎么辦?”等等。所以即使這段極其簡短的代碼也要求人們了解對象字面量、數(shù)組、變量、字符串、如何獲取 DOM 元素的引用、事件、 DOM 樹何時構(gòu)建完畢等等更多知識。這些對于程序員來說微不足道的事情,對于不會 JavaScript 、只會寫 HTML 的人來說都是一場艱難的攻堅戰(zhàn)。
現(xiàn)在來看一下 HTML5 中的等效聲明性代碼:
html<div class="ui-widget">
<label for="tags">Tags: </label>
<input id="tags" list="languages">
<datalist id="languages">
<option>ActionScript</option>
<option>AppleScript</option>
<option>Asp</option>
<option>BASIC</option>
<option>C</option>
</datalist>
</div>
這不僅讓寫 HTML 的人看得更清楚更明白,也對程序員來說更為簡單。我們看到所有的內(nèi)容都同時被設(shè)置好,不必關(guān)心什么時候初始化、如何獲取元素的引用以及如何設(shè)置每個內(nèi)容,無需知道哪個函數(shù)是用來初始化或者它需要什么參數(shù)。在更高級的使用情況中,還會添加一個 JavaScript API 來允許動態(tài)創(chuàng)建屬性和元素。這遵循了一條最基本的 API 設(shè)計原則:讓簡單的內(nèi)容變得更簡單,讓復(fù)雜的內(nèi)容得以簡單實現(xiàn)。
這給我們上了一堂關(guān)于 HTML API 的重要一課:HTML API 不光要給那些了解 JavaScript 但水平有限的人帶來福音,還要讓我們程序員在普通的工作中也要不惜犧牲程序的靈活性來換取更高的表述性。然而不知道為什么,我們在寫自己的類庫的時卻總忘記這些原則。
那么什么是 HTML API 呢?根據(jù)維基百科的定義,API(也就是應(yīng)用程序接口)是“用于構(gòu)建應(yīng)用程序軟件的一組子程序定義、協(xié)議和工具”。在 HTML API 中,定義和協(xié)議就是 HTML ,工具在 HTML 中配置。HTML API 通常由可用于現(xiàn)有 HTML 內(nèi)容的類和屬性模式組成。通過 Web 組件,甚至可以像玩游戲一般自定義元素名稱和 Shadow DOM,HTML API 甚至能擁有完整的內(nèi)部結(jié)構(gòu),并且對頁面其余部分隱藏實現(xiàn)細(xì)節(jié)。但是這并不是一篇關(guān)于 Web 組件的文章,Web 組件給予了 HTML API 設(shè)計者更多的能力和選擇,但是良好的(HTML)API 設(shè)計原則都是可以舉一反三的。
HTML API 加強了設(shè)計師和工程師之間的合作,減輕工程師肩上的工作負(fù)擔(dān),還能讓設(shè)計師創(chuàng)造更具還原度的原型。在類庫中引入 HTML API 不僅讓社區(qū)更具包容性,最終還能造福程序員。
并不是每個類庫都需要 HTML API。 HTML API 在使用了 UI 元素的類庫中非常有用,比如 galleries、drag-and-drop、accordions、tabs、carousels 等等。經(jīng)驗表明,如果一個非程序員不能理解該類庫的功能,它就不需要 HTML API。比如,那些簡化代碼或者幫助管理代碼的庫就不需要 HTML API。那 MVC 框架或者 DOM 助手之類的庫又怎會需要 HTML API 呢?
目前為止,我們只討論了 HTML API 的定義、功能和用處,文章剩下的部分是關(guān)于如何設(shè)計一個好的 HTML API。
在 JavaScript API 中,初始化是被類庫的用戶嚴(yán)格控制的:因為他們必須手動調(diào)用函數(shù)或者創(chuàng)建對象,精確地控制著其運行的時間和基礎(chǔ)。在 HTML API 中,我們要幫用戶選擇,同時也要確保不會妨礙那些仍然使用 JavaScript 的用戶,因為他們可能希望得到完全控制。
最常見的兼容兩種使用場景的辦法是:只有匹配到給定選擇器(通常是一個特定的類)時才會自動初始化。Awesomplete 就是采用的這種方法,只選取具有 class="awesomplete" 的 input 元素進(jìn)行初始化。
有時候,簡化自動初始化比做顯式選擇初始化更重要。當(dāng)你的類庫需要運行在眾多元素之上時,避免手動給每個元素單獨添加類比顯式選擇初始化更加重要。比如,Prism 自動高亮任何包含 language-xxx 類的 <code> 元素(HTML5 的說明中建議指定代碼段的語言)及其包含languate-xxx 類的元素內(nèi)部的 <code> 元素。這是因為 Prism 可能會用在一個有著成千上萬代碼段的博客系統(tǒng)中,回過頭去給每一個元素添加類將會是一項非常巨大的工程。
在可以自由地使用 init 選擇器的情況下,最好的做法是允許選擇是否自動化。比如,Stretchy 默認(rèn)自動調(diào)整每個 <input>、<select> 和 <textarea>的尺寸,但是也允許通過 data-stretchy-filter 屬性自定義指定其他元素為 init 選擇器。Prism 支持 <script> 元素的 data-manual 屬性來完全取消自動初始化。良好的實踐應(yīng)該允許 HTML 和 JavaScript 都能設(shè)置這個選項,來適應(yīng) HTML 和 JavaScript 兩種類庫的用戶。
那么,對于 init 選擇器的每個元素,你的類庫都需要有一個封包、三個內(nèi)部的按鈕和兩個相鄰的 div 該怎么辦呢?小問題,自己生成就好了。但是這種瑣碎的工作更適合機器,而不是人。不要期望每個使用類庫的人都同時使用了模板系統(tǒng):許多人還在使用手動添加標(biāo)記,他們會發(fā)現(xiàn)這樣建造系統(tǒng)太過復(fù)雜。因此,我們應(yīng)該讓他們更輕松些。
這種做法也最小化了錯誤風(fēng)險:如果一個用戶僅僅引入了用來初始化的類卻沒有引入所有需要的標(biāo)記怎么辦?如果不需要添加額外的標(biāo)記,就不會產(chǎn)生錯誤。
這條規(guī)則中有一個例外:優(yōu)雅地退化并漸進(jìn)地增強。比如,即使單個具有 data- * 屬性的元素并在 data-* 中添加所有選項就可以實現(xiàn),在嵌入推文的時候也還是會涉及很多標(biāo)記。這樣做是為了在 JavaScript 加載和運行之前推文就可讀。一個良好的經(jīng)驗法則就是捫心自問“即使在沒有 JavaScript ,多余的標(biāo)記能否給終端用戶帶來好處?”如果是,那么就引入;如果不是,那就要用類庫生成。
便于用戶使用還是讓用戶自定義也是一組經(jīng)典的矛盾:自動生成所有的標(biāo)記會易于用戶使用,讓用戶自定義又顯得更加靈活。在你需要的時候,靈活性如雪中送炭,在不需要的時候卻適得其反,因為你不得不手動設(shè)置所有的參數(shù)。為了平衡這兩種需要,你可以生成那些需要但不存在的標(biāo)記。比如,假設(shè)你需要給所有的 .foo 元素外層添加一個 .foo-container 元素。首先,通過element.closest(".foo-container") 檢查 .foo 元素的父元素或者任何的祖先元素(這樣最好了)是否含有 foo-container 類,如果有的話,你就不用生成新的元素,直接使用就可以了。
通常,設(shè)置應(yīng)該通過在恰當(dāng)?shù)脑厣鲜褂?data-* 屬性來實現(xiàn)。如果你的類庫中添加了成千上萬的屬性,然后你希望給它們添加命名空間來避免和其他類庫混淆,比如這樣 data-foo-*(foo 是基于類庫名字的一到三個字母長度的前綴)。如果名字顯得太長,你可以使用 foo-*,但你要知道,這種方式會打破 HTML 驗證并且會使得一些勤奮的 HTML 作者因此而棄用你的類庫。理想情況下,只要代碼不會太臃腫,以上兩種情況都應(yīng)該支持。目前還沒有完美的解決辦法,因此在 WHATWG 中展開了一場如火如荼的討論:是否應(yīng)該讓自定義的屬性前綴合法化。
盡可能地遵從 HTML 的慣例。比如,你使用了一個屬性來做布爾類型的設(shè)置,當(dāng)該屬性出現(xiàn)時無論其值如何都被視為 true,若不出現(xiàn)則被視為 false,不要期望可以用 data-foo="true" 或者 data-foo="false" 來代替。
你也可以使用類進(jìn)行布爾值設(shè)置。一般情況下它的語法和布爾屬性類似:類存在的時候是 true 不出現(xiàn)的時候就是 false。如果你想反過來設(shè)置,那就用一個 no- 前綴(比如,no-line-number)。但是要記住,類名可不像屬性一樣只有 data-*,因此這種方式很可能會和用戶現(xiàn)存的類名沖突,因此你可以考慮一下在類名中使用 foo- 這樣的前綴來避免沖突。但也有可能在后期的維護(hù)中發(fā)現(xiàn)這些類并未被 CSS 使用所以誤刪,這又是另一個隱患。
當(dāng)你需要設(shè)置一組相關(guān)的布爾值時,使用空格區(qū)分會比使用多個分隔符的方式好很多。
html<!-- 第一種-->
<div data-permissions="read add edit delete save logout">
html<!-- 第二種-->
<div data-read data-add data-edit data-delete data-save data-logout">
html <!-- 第三種-->
<div class="read add edit delete save logout">
比如,第一種當(dāng)時就比后面兩種好得多,因為后者可能會造成很多的沖突。你還可以使用 ~= 屬性選擇器來定位單個元素,比如 element.matches("[data-permissions~=read]") 可以檢查該元素是否有 read 權(quán)限。
如果設(shè)置內(nèi)容的類型是數(shù)組(array)或者對象(object) ,那么你就可以使用 data-* 屬性來關(guān)聯(lián)到另一個元素。比如, HTML5 中的自動完成:因為自動完成需要一個建議列表,你可以使用 data-* 屬性并通過 ID 聯(lián)系到包含建議內(nèi)容的 <datalist> 元素。
HTML 有一個慣例很讓人頭痛:在 HTML 中,用屬性聯(lián)系到另一個元素通常是靠引用其 ID 實現(xiàn)的(試想一下 <label for="...">)。然而,這種方法相當(dāng)受限制:如果能夠允許使用選擇器或者甚至允許嵌套將更為方便,其效果將會極大地依賴于你的使用情況。要記住,穩(wěn)定性重要,但實用性更加重要。
即使有些設(shè)置內(nèi)容不能在 HTML 中指定也沒關(guān)系。在 JavaScript 中以函數(shù)為設(shè)置值的部分被稱作“高級自定義”。試想一下 Awesomplete:所有數(shù)字、布爾值、字符串和對象都可以通過 data-* 屬性(list、minChars、maxItems、autoFirst)設(shè)置,所有的函數(shù)設(shè)置只能通過 JavaScript 使用(filter、sort、item、replace、data),這樣會寫 JavaScript 函數(shù)來配置類庫的人就可以使用 JavaScript API 了。
正則表達(dá)式(regex)處在灰色地帶:通常只有程序員才知道正則表達(dá)式(甚至程序員在使用的時候也會有問題!);那么,乍看之下,在 HTML API 中引入正則表達(dá)式類型的設(shè)置并沒有意義。然而,HTML5 確實引入了這樣的設(shè)置(<input pattern="regex">),并且我覺得很成功,因為非程序員能在正則詞典中找到他們的用例并復(fù)制粘貼。
如果你的 UI 庫在每個頁面只會調(diào)用一兩次,繼承可能不是很重要。然而,如果要應(yīng)用于多個元素,通過類或者屬性給每個元素做相同的配置將會非常令人頭疼。咱要記住并不是每個人都用了構(gòu)建系統(tǒng),尤其是非程序員。在這些情況下,定義能夠從祖先元素繼承設(shè)置將會變得非常有用,那樣多個實例就可以被批量設(shè)置了。
還拿 Smashing Magazine 中使用的時下流行的語法高亮類庫 —— Prism 來舉例。高亮語句是通過 language-xxx 形式的類來配置的。如你所見,這違反了我們在前文中談過的規(guī)則,但這只是一種主觀決策,因為 HTML5 手冊中建議如此。在有許多代碼段的頁面上(想象一下,在博客文章中使用內(nèi)聯(lián) <code> 元素的頻率!),在每個 <code> 元素中指定代碼語句將會非常煩人。為了減輕這種痛苦,Prism 支持繼承這些類:如果一個 <code> 元素自己沒有 language-xxx 類,那么將會使用其最近的祖先元素的 language-xxx 類。這使得用戶可以設(shè)置全局的代碼語句(通過在 <body> 或者 <html> 元素上設(shè)置類)或者設(shè)置區(qū)塊的代碼語句,并且可以在擁有不同語句的元素或者區(qū)塊上重寫設(shè)置。
現(xiàn)在 CSS 變量已經(jīng)被所有的瀏覽器支持,它們可以用于以下設(shè)置:他們默認(rèn)可以被繼承,并且可以以內(nèi)聯(lián)的方式通過 style 屬性設(shè)置,也可以通過 CSS 或者 JavaScript 設(shè)置。在代碼中,你可以通過getComputedStyle(element).getPropertyValue("--variablename") 獲取它們。除了瀏覽器支持,其主要的劣勢就是開發(fā)者們還沒習(xí)慣使用它們,但是那已經(jīng)發(fā)生改變了。并且,你不能像監(jiān)視元素和屬性的一般通過 MutationObserver 來監(jiān)視其改變。
大多數(shù) UI 類庫都有兩組設(shè)置:定義每個組件表現(xiàn)形式的設(shè)置和定義整個類庫表現(xiàn)形式的全局設(shè)置。目前為止,我們主要討論了前者,你現(xiàn)在可能好奇全局設(shè)置該在設(shè)置在哪里。
進(jìn)行全局設(shè)置的一個好地方就引入類庫的 <script> 元素。你可以通過 document.currentScript 獲取該元素,這有著非常好的瀏覽器支持。好處就是,這對于設(shè)置的作用域非常清楚,因此它們的名字可以起的更短(比如 data-filter 而不是 data-stretchy-filter)。
然而,你不能只在 <script> 元素中進(jìn)行設(shè)置,因為一些用戶可能會在 CMS 中使用你的類庫,而 CMS 中不允許用戶自定義 <script> 元素。你也可以在 <html> 和 <body> 元素或者甚至任何地方設(shè)置,只要你清楚地聲明了屬性值重復(fù)的時候哪個會生效。
那么,你已經(jīng)掌握了如何在類庫中設(shè)置一個漂亮的聲明性的 API,那自然很好,然而,如果你所有的文檔都寫得只有會 JavaScript 的用戶才看得懂,那么就只有很少人能使用了。我記得曾經(jīng)看過一個很酷的類庫,基于 URL 并通過切換元素的 HTML 屬性來切換元素的表現(xiàn)形式。然而,這漂亮的 HTML API 并不能被其目標(biāo)人群所使用,因為整篇文檔中都充滿了 JavaScript 引用。最開始的例子開頭就是“這和 location.href.match(/foo/)等價”。非程序員哪能看懂這個呀?
同時要記得許多人并不會任何編程語言而不僅僅是 JavaScript。你希望用戶能夠讀懂并理解的文中的模型、視圖、控制器或者其他軟件工程觀念,但結(jié)果無非是讓他們感到迷惑。
當(dāng)然,你應(yīng)該在文檔中寫 API 里 JavaScript 的內(nèi)容,你可以寫在“高級使用”部分。然而,如果你在文檔一開頭就引用 JavaScript 對象和函數(shù)或者軟件工程的觀念,那么你實質(zhì)上就是在告訴非程序員這個類庫不是給他們用的,因此你就排除了一大批潛在用戶。不幸的是,大部分的 HTML API 類庫文檔都受這些問題困擾著,因為 HTML API 經(jīng)常被視為是程序員的捷徑,而并不是給非程序員使用的。慶幸的是,這種狀況在未來可以有改變。
在不遠(yuǎn)的未來,Web 組件百分之百將會徹底改變 HTML API。<template> 元素將會允許作者提供惰性加載的腳本。自定義元素將使得用戶可以像原生的 HTML 一樣使用更多優(yōu)雅的 init 標(biāo)記。引入 HTML 也將使得作者能夠僅引入一個文件來替代三個樣式表、五個腳本和十個模板(如果瀏覽器能夠同時獲取并且不再認(rèn)為 ES6 模塊是一種競爭技術(shù))。Shadow DOM 使得類庫可以將復(fù)雜的 DOM 結(jié)構(gòu)適當(dāng)壓縮并且不會影響用戶自己的標(biāo)記。
然而除了 <template>,瀏覽器對其他三個特征的支持目前受限。因此他們需要更高的聚合度,以此來減少對類庫的影響。這將會是我們在未來一段時間里需要不斷關(guān)注的東西。
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。