《精通javascript》5,6章小結(二)

來源:互聯網
上載者:User

  繼續5,6章小結(一)的內容,作者認為我們會用css中的選擇符來定位HTML DOM中的元素,給其添加樣式,那麼為什麼不利用css選擇符來定位得到我們想要的DOM節點呢,由於這樣的想法產生了jquery中靈活強大的選取器(selector)協助定位尋找元素,作者也簡要說明了下xpath。

如何獲得一個元素的常值內容,如:<p><strong>hello</strong>how are you doing?</p>

假定<strong>對應strongElem那麼 strongElem.innerText //非Mozilla核心的瀏覽器

                                                   strongElem.firstChild.nodeValue  //適合所有平台

文中給出了一個通用的取出元素常值內容的函數

function  text(e) {

  var t = "";

     //如果單個元素傳入,擷取它的子節點

     //否則假設e是個節點數組

     e = e.childNodes || e;

     //遍曆所有的子節點

     for(var j = 0; j < e.length; j++) {

       //如果不是一個元素,追加到t

           //否則遞迴遍曆它的所有子節點

           t += e[j].nodeType != 1 ?  e[j].nodeValue : text(e[j].childNodes); 

    }

    //返回匹配的文本

    return t;

}

擷取一個元素內的HTML,我們很快會想到innerHTML,但它只對HTML DOM有效對XML DOM就不行了。

關於元素的屬性,有個判定一個元素是否具有某個指定屬性的方法

function hasAttribute(elem, name) {

  return elem.getAttribute(name) != null;

}

一對HTML,XML DOM的通用方法:getAttribute和setAttribute  例:id("everywhere").getAttribute("id") ;

                                                                                           tag("input")[0].setAttribute("value", "your name");

除了這對標準的方法,還有一些快速存取元素屬性的方式,如:tag("div")[0].id = "main";           tag("input")[0].value;

但是有一些屬性如class --> className,  float-->cssFloat,  text-->cssText,因為像class,float,text這些詞本來就是javascript中的保留字。

文中有個attr方法,通過參數個數決定它的作用是設定屬性值,還是擷取屬性值:

function attr(elem, name, value) {

  //確保提供了一個有效name

      if(!name || name.constructor != String) return "";

      //理解不合常規的命名

      name = {'for':'htmlFor', 'class':'className'}[name] || name;

      //如果使用者傳入value

      if(typeof value != 'undefined') {

        //先用快速存取法

            elem[name] = value;

            //如果可以,用標準的setAttribute

            if(elem.setAttribute)  elem.setAttribute(name, value);

      }

       //返回屬性值

       return elem[name] || elem.getAttribute(name) || '';

}

這個方法既能讀又能取,參數中如果不帶value那麼返回已有的屬性值,如果帶了value,那麼給對應的屬性設定值,這和jquery中的attr基本是一樣的,只不過我們用jquery的時候把DOM元素封裝成了jquery對象。

修改DOM包括建立,插入,刪除等,有了這些我們就能打造動態頁面效果,xhtml是xml一個子集,在建立元素時帶個namespace

function create(elem) {

  return document.createElementNS ?

                  document.createElementNS('http://www.w3.org/1999/xhtml', elem) :

                  document.createElement(elem);

}

對於插入DOM,有兩個標準方法:parentBeforeNode.insertBefore(nodeToInsert, beforeNode)

                                           parentElem.append(nodeToInsert)

相信大家對這兩個方法並不陌生,書中基於這兩個方法做了函數封裝

function before(parent, before, elem) {

  //檢查是否提供父節點,如果像這樣調用:before(elem1, elem2)將elem2插到elem1之前

      if(elem == null) {

       elem = before;

          before = parent;

          parent = before.parentNode;

      }

      parent.insertBefore(checkElem(elem), before);

}

function append(parent, elem) {

  parent.appendChild(checkElem(elem));

}

function checkElem(elem) {

  //如果傳入的是個字串,那麼轉換成TextNode

      return elem && elem.constructor == String ?

                      document.createTextNode(elem) : elem;

}

向元素中注入HTML,tag("ul")[0].innerHTML = "<li>Cats</li><li>Dogs</li><li>Mice</li>";

比起上面的方法來說,確實方便,但用innerHTML有以下缺點:

1.就像之前提到的,它不支援純粹的XML

2.innerHTML的賦值是把元素內的內容全部覆蓋掉,很不靈活

文章中作者給出了一個很不錯的解決方案:

function checkElem(a) {

  var r = [];

      //如果a不是數組,把a初始化為數組

      if(a.constructor != Array) a = [a];

      for(var i = 0; i < a.length; i++) {

        //如果是構造HTML字串

    if(a[i].constructor == String) {

             //建立一個臨時元素來持有HTML

                 var div = document.createElement("div");

       //注入這個HTML,把它轉變成DOM結構

                 div.innerHTML = a[i];

                 //從這個臨時的div中取出DOM元素

                 for(var j = 0; j < div.childNodes.length; j++) {

                   r[r.length] = div.childNodes[j];

                 }

            } else if (a[i].length) {

       //如果是它是個數組,假設是個DOM節點的數組

                  for(var j = 0; j < a[i].length; j++)

                           r[r.length] = a[i][j];

            } else { //否則就假設它是個DOM節點

        r[r.length]  = a[i];

            }

     return r; //參數a解析後的dom節點數組

      }

}

再把原來的before,append函數擴充下:

function before(parent, before, elem) {

  if(elem == null) {

       elem = before;

           before = parent;

           parent = before.parentNode;

      }

      //得到新的元素數組

      var elems = checkElem(elem);

      //倒序遍曆數組elems

      for(var i = elems.length - 1; i >= 0; i--)

                parent.insertBefore(elems[i], before);

}

function append(parent, elem) {

  var elems = checkElem(elem);

      for(var i = 0; i < elems.length; i++)

               parent.appendChild(elems[i]);

}

然後我們就可以這樣調用了append(first(tag('ul')[0]), '<li>Mouse trap.</li>');而之前第二個參數只能是個單獨的節點(如<p>,<li>或者textNode);如此一來大大增強了可用性。

小結的第二部分就到這吧。。測試代碼下載

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.