前言
接上一次的話題,我們今天繼續學習,對于上一篇文章,有朋友認為這種文章滿大街都是(老實說,我也沒想到這麼多朋友願意讀),想學javascript不如自己買一本javascript進階程式設計來讀讀,其實這些朋友的想法是正确的。
但無奈這是上面下的任務,而且我認為學習有兩個最為困難的階段:
1 入門
2 飛升
我所說的飛升到不是說非常非常厲害,也就是我兩年後想達到的水準罷了。
誠然入門不難,認為不難的同學其實是錯誤的,說他不難隻能說你已經入門了,其實入門真的很難的!
就拿我來說,我入門CSS就花了很大的功夫,連現在我都覺得CSS很精秒。
我自己js入門沒有我沒有辦法斷定。什麼程度算是入門,什麼程度算是精通,各個人的标準都不相同,有的同學認為我js不錯,其實我自己知道我事實上還差得遠呢!
人人都想飛升,人人都想當“湯姆大叔”,我當然也想當大牛,拿寫文章來說,一來想激勵自己,二來發文章真的是一種很好的學習方式呢!
我建議大家多發技術部落格,不管好壞都發!回看我兩年前的東西,隻能用慘不忍睹來形容,我兩年後回看現在的部落格,也許我仍然會認為慘不忍睹,那時候我便已經成為“湯姆大叔”也說不定呢,呵呵。
另外,對于不能入門的同學,迷茫是很大一個因素,二個月前我也非常迷茫,我也希望有同學能盡快找回自己的專注,丢掉他的迷茫,大家共同進步,是以這種部落格我還是會發的,而且會堅持發下去。正如我讀張鑫旭部落格時看到了他的那份專注進而引燃自己的那份執着。
好了,扯得很遠了,繼續我們今天的任務吧。
DOM
有些朋友記憶很差的,很不幸我就是其中之一,我從來就沒有把這個家夥事什麼記清楚過!于是我就隻能用中文讀出來,有一次一個朋友用英文讀了出來,我硬是不知道是什麼東西!他活生生的将我帶回了高中時我花了一早上硬是記不住幾個單詞的痛苦場景!
Document Object Model 文檔對象模型
一個Window對象有一個document屬性引用了Document對象
Document對象表示視窗内容,他是一個巨大的API中的核心對象,他代表操作文檔的内容
了解DOM我們需要了解:
1 在文檔中查詢元素
2 将文檔作為節點樹來周遊,找的節點的祖先、兄弟和後代
3 查詢和設定文檔的屬性
4 查詢、更改文檔的内容
5 建立、插入、删除節點來修改文檔
DOM對象模型是表示和操作HTML和XML文檔内容的基本API,這個家夥說是不複雜,但是畫圖要好久呢:
複制代碼
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>刀狂劍癡</title>
</head>
<body>
<h1>
葉小钗</h1>
<p>
葉小钗·<strong>中原劍聖</strong></p>
</body>
</html>
擷取文檔元素
根據ID選擇dom元素每個朋友都知道,這裡真心多此一舉了,但是jquery出現後卻讓一切變得不那麼明顯了:
<script type="text/javascript">
var h = document.getElementById('h');
var p = document.getElementById('p');
var strong = document.getElementById('strong');
var s = '';
</script>
<h1 id="h">
<p id="p">
葉小钗·<strong id="strong">中原劍聖</strong></p>
這裡我一來就犯了一個錯誤,在dom還沒有生成的情況下去擷取,當然擷取不到!這裡我老老實實将js放到一頁尾去了
于是我們來好好的觀察一下這些家夥:
框住的東西都是需要注意的(并且關于樣式的東西在IE中還會有相容的問題),我們一般不必關心這些東西,但是真正用到的時候要知道如何查詢才行
name選擇
<h1 id="h" name="w">
<p name="w">
1</p>
2</p>
3</p>
4</p>
var p = document.getElementsByName('w');
根據name可以選擇一個群:
标簽選擇
var p = document.getElementsByTagName('p');
與上面一緻,這些看起來都很簡單似的,那麼我們現在要擷取一個東東,在不使用id,不使用jquery其實并不像我們想的那麼簡單:
比如:我要擷取這麼一個東東:
<div class="yxc">
<div id="p">
葉小钗·<strong id="strong">中原劍聖</strong></div>
<div name="w">
1</div>
<p>
</p>
<p class="come">
來吧,擷取我吧,我是你的了1</p>
來吧,擷取我吧,我是你的了2</p>
<p class="ccc come">
<p class="vvv">
</div>
</div>
認為簡單的同學去擷取他吧,反正就是擷取具有come css的元素,不許使用HTML5的東西哦,我不知道你痛苦不,我反正十分痛苦:
var dom = [];
var ps = document.getElementsByTagName('div')[0].children[3].children;
for (var i = 0, len = ps.length; i < len; i++) {
var el = ps[i];
for (var j = 0; j < el.classList.length; j++) {
if (el.classList[j] == 'come') {
dom.push(el);
break;
}
}
}
屬性
HTML由一個标簽和一組稱為屬性飛鍵值對組成,我們一般使用getAttribute與setAttribute來擷取與設定屬性(使用.的方式也可以,但是這個更标準)。
因為屬性無法使用delete删除,是以還提供了hasAttribute與removeAttribute來判斷标簽是否含有某屬性以及去掉标簽的某個屬性。
自定義屬性
我平時定義自定義屬性時候五花八門,是以便需要用到set/getAttribute,但是這樣卻破壞了HTML的有效性,這樣并不好。
HTML5中,提供一種解決方案,任何以data-字首的自定義屬性認為是合法的,是以我們以後的自定義屬性還是需要注意的,
為了支援data-的屬性,HTML5特别提供dataset屬性擷取去掉字首的屬性對象,為了相容之前的浏覽器,估計這個用得不多。
擷取HTML元素的内容
這個東東其實沒有什麼說的:
innerHTML擷取元素内部所有文本和标簽
innerText擷取元素内部文本
outerHTML擷取标簽元素
需要注意的是,在一些浏覽器中式不能直接操作tr與table的innerHTML的。
建立、插入、删除
我們有時候會異步加載js,于是會有以下代碼:
function loadAsncJs(url) {
var head = document.getElementsByName('head')[0];
var s = document.createElement('script');
s.setAttribute('src', url); //s.src=url
head.appendChild(s);
插入節點有兩種方法:appendChild與insertBefore
insertBefore提供兩個參數:
1 待插入節點
2 已存在節點
新節點會插入其前面,第二個參數為空的話,其表現與appendChild一緻
删除節點就比較詭異了,因為他能直接删除,而是發生在節點的父元素上:
//比如我們要删除el需要這樣做:
el.parentNode.removeChild(el);
另外我若是想替換一個節點,可以這樣做:
el.parentNode.replace(newDom);
節點坐标與視口坐标
節點坐标便是元素相對于left與top的距離;
而視口坐标便是元素目前在浏覽器的位置,比如y坐标本來是200但是滾動了70,那麼其視口坐标便是130;
視口坐标的使用十分普遍,我們經常就會拖動元素,是以還是需要掌握的,但是這裡的相容性問題還是不少的:
擷取視窗滾動條位置
Window對象的pageXOffset與pageYOffset基本所有浏覽器都支援,當然我們的IE會站出來說“不”!
是以我們使用的最常用的還是scrollLeft與scrollTop屬性來擷取滾動條位置
但是正常情況下查詢文檔的跟節點就能擷取,怪異模式時候變需要使用到body元素了,這個坑可大了!
function getScrollOffset(w) {
w = w || window; //可能是iframe
if (w.pageXOffset != null) {
return { x: w.pageXOffset, y: w.pageYOffset };
//标準浏覽器情況下
var d = w.document;
if (document.compatMode == 'CSS1Compat') {
return { x: d.documentElement.scrollLeft, y: d.documentElement.scrollTop };
//怪異模式
return { x: d.body.scrollLeft, y: d.body.scrollTop };
查詢元素的幾何尺寸
擷取元素的尺寸的應用也非常多,我今天才用到了呢,而且在手機上還錯了呢。。。
有些時候本來你認為比較不好獲得的東西,其實他就在那裡了,getBoundingClientRect直接告訴了我們答案:
var ss = document.getElementById('w').getBoundingClientRect();
其中的width和height有一點相容性問題,使用時候最好用right-left擷取寬度
注意:需要定位到元素上需要加上滾動距離,并且該方法的相容性無法确定,我們還是老老實實的使用offsetWidth等屬性吧:
function getOffset(el) {
if (!el) return null;
return {
x: el.offsetLeft,
y: el.offsetTop,
width: el.offsetWidth,
height: el.offsetHeight
};
判斷元素是否在某點
看到此屬性時,我首先想到的就是e屬性,典型應用就是判斷滑鼠點在了什麼上:
Document的elementFromPoint方法可以判斷指定坐标上有什麼元素!
當滑鼠資訊出現在e中的那一刻,該方法的意義就不大了
有意思的東東
var cookie = document.cookie;
var domain = document.domain;
var referrer = document.referrer; //上一文檔的url
var location = document.location;
查詢選取文本
有時候我們需要判斷使用者選取了哪些文本,并做處理:
function getSecText() {
if (window.getSection) {
return window.getSelection(); //html5
} else if (document.selection){
return document.selection.createRange().text;
BOM
浏覽器對象模型 Browser Object Model
說白點就是window這個東東:表示浏覽器的一個執行個體,是通路浏覽器視窗的一個接口,也是ECMAScript規定的Global對象。
意思是我們定義的是以所有的東西,都與window有關,他是用戶端給javascript程式的全局對象。
計時器
javascript的計時器有setTimeout與setInterval兩種,一個是在一定時間後執行,一個是重複執行。
這兩個東西大家應該都很熟悉了,但是在實際應用中,setTimeout卻帶給了我們不一樣的東西,比如優化!
setTimeout的優化點可以是以下地方:
① 滑鼠移動标簽上加載資料(發起http請求),但我們滑鼠可能無意義的劃過,是以延遲點加載若是無意義請求便取消
② 無論滑鼠事件或者視窗改變事件,我們都可以使用這個家夥
一個簡單的例子:
(function () {
var ajax = $('#ajax');
var TIMER = null;
var TIMER_STEP = 500;
ajax.mousemove(loadMenu);
ajax.mouseout(function () {
if (TIMER) clearTimeout(TIMER);
});
function loadMenu() {
TIMER = setTimeout(function () {
//do someting
}, TIMER_STEP);
}
})();
浏覽器的定位和導航
對URL的請求總是非常常見的,location對象的擷取便可處理之,比如我們經常想擷取url 的參數:
function getUrlParam(name) {
var args = {};
var query = document.location.search.substring(1); //去掉?
var arr_param = query.split('&');
for (var i = 0, len = arr_param.length; i < len; i++) {
var arr_tmp = arr_param[i].split('=');
if (arr_tmp.length == 2) {
args[arr_tmp[0]] = decodeURIComponent(arr_tmp[1]);
if (name && args[name]) return args[name];
return args;
var p = getUrlParam();
結語
今天暫時到這,昨天晚上樓下有幾個當兵的喝酒聊天搞到3點鐘,我這裡确實被搞崩潰了,而且又不敢去說點什麼。。。。這裡住了幾百戶人也沒人去說下。。。
當兵的真嚣張啊。。。。我們下次繼續吧,若是我不再寫部落格了就一定當兵去了,大家不要想念我。
本文轉自葉小钗部落格園部落格,原文連結http://www.cnblogs.com/yexiaochai/archive/2013/05/28/3102674.html,如需轉載請自行聯系原作者