zoukankan      html  css  js  c++  java
  • 《精通javascript》5,6章小结(二)

      继续5,6章小结(一)的内容,作者认为我们会用css中的选择符来定位HTML DOM中的元素,给其添加样式,那么为什么不利用css选择符来定位得到我们想要的DOM节点呢,由于这样的想法产生了jquery中灵活强大的选择器(selector)帮助定位查找元素,作者也简要说明了下xpath

    如何获得一个元素的文本内容,如:

    1 <p><strong>hello</strong>how are you doing?</p>

    假定<strong>对应strongElem那么:

    1     strongElem.innerText; //非Mozilla内核的浏览器
    2     
    3     strongElem.firstChild.nodeValue;  //适合所有平台

    文中给出了一个通用的取出元素文本内容的函数

     1     function text(e) {
     2         var t = "";
     3         
     4         //如果单个元素传入,获取它的子节点
     5         //否则假设e是个节点数组
     6         e = e.childNodes || e;
     7         
     8         //遍历所有的子节点
     9         for(var j = 0; j < e.length; j++) {
    10           //如果不是一个元素,追加到t
    11             //否则递归遍历它的所有子节点
    12             t += e[j].nodeType != 1 ?  e[j].nodeValue : text(e[j].childNodes); 
    13         }
    14         //返回匹配的文本
    15           
    16         return t;
    17     }

    获取一个元素内的HTML,我们很快会想到innerHTML,但它只对HTML DOM有效对XML DOM就不行了。

    关于元素的属性,有个判定一个元素是否具有某个指定属性的方法

    1     function hasAttribute(elem, name) {
    2         return elem.getAttribute(name) !== null;
    3     }

    一对HTML,XML DOM的通用方法:getAttribute和setAttribute  例:

    1     id("everywhere").getAttribute("id") ;
    2 
    3     tag("input")[0].setAttribute("value", "your name");

    除了这对标准的方法,还有一些快速访问元素属性的方式,如:

    1     tag("div")[0].id = "main";
    2 
    3     tag("input")[0].value;

    但是有一些属性如class --> className,  float-->cssFloat,  text-->cssText,因为像class,float,text这些词本来就是javascript中的保留字。

    文中有个attr方法,通过参数个数决定它的作用是设置属性值,还是获取属性值:

     1     function attr(elem, name, value) {
     2         //确保提供了一个有效的name
     3         if(!name || name.constructor != String) return "";
     4 
     5         //理解不合常规的命名
     6         name = {'for':'htmlFor', 'class':'className'}[name] || name;
     7 
     8         //如果用户传入value
     9         if(typeof value != 'undefined') {
    10             //先用快速访问法
    11             elem[name] = value;
    12 
    13             //如果可以,用标准的setAttribute
    14             if(elem.setAttribute)  elem.setAttribute(name, value);
    15         }
    16 
    17         //返回属性值
    18         return elem[name] || elem.getAttribute(name) || '';
    19     }

    这个方法既能读又能取,参数中如果不带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,有两个标准方法:

    1     parentBeforeNode.insertBefore(nodeToInsert, beforeNode)
    2 
    3     parentElem.append(nodeToInsert)

    相信大家对这两个方法并不陌生,书中基于这两个方法做了函数封装

     1     function before(parent, before, elem) {
     2 
     3         //检查是否提供父节点,如果像这样调用:before(elem1, elem2)将elem2插到elem1之前
     4         if(elem == null) {
     5             elem = before;
     6             before = parent;
     7             parent = before.parentNode;
     8         }
     9 
    10         parent.insertBefore(checkElem(elem), before);
    11 
    12     }
    13 
    14     function append(parent, elem) {
    15         parent.appendChild(checkElem(elem));
    16     }
    17 
    18     function checkElem(elem) {
    19         //如果传入的是个字符串,那么转换成TextNode
    20         return elem && elem.constructor == String ?
    21             document.createTextNode(elem) : elem;
    22     }

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

    比起上面的方法来说,确实方便,但用innerHTML有以下缺点:

    1.就像之前提到的,它不支持纯粹的XML

    2.innerHTML的赋值是把元素内的内容全部覆盖掉,很不灵活

    文章中作者给出了一个很不错的解决方案:

     1     function checkElem(a) {
     2         var r = [];
     3         
     4         //如果a不是数组,把a初始化为数组
     5         if(a.constructor != Array) a = [a];
     6         
     7         for(var i = 0; i < a.length; i++) {
     8         
     9             //如果是构造HTML字符串
    10             if(a[i].constructor == String) {
    11                 //创建一个临时元素来持有HTML
    12                 var div = document.createElement("div");
    13                 
    14                 //注入这个HTML,把它转变成DOM结构
    15                 div.innerHTML = a[i];
    16                 
    17                 //从这个临时的div中取出DOM元素
    18                 for(var j = 0; j < div.childNodes.length; j++) {
    19                     r[r.length] = div.childNodes[j];
    20                 }
    21 
    22             } else if (a[i].length) {
    23                 //如果是它是个数组,假设是个DOM节点的数组
    24                 for(var j = 0; j < a[i].length; j++) {
    25                     r[r.length] = a[i][j];
    26                 } 
    27             else { 
    28                 //否则就假设它是个DOM节点
    29                 r[r.length]  = a[i];
    30             }
    31                 
    32             return r; //参数a解析后的dom节点数组
    33         }
    34     }

    再把原来的before,append函数扩展下:

     1     function before(parent, before, elem) {
     2         if(elem == null) {
     3             elem = before;
     4             before = parent;
     5             parent = before.parentNode;
     6         }
     7 
     8         //得到新的元素数组
     9         var elems = checkElem(elem);
    10 
    11         //倒序遍历数组elems
    12         for(var i = elems.length - 1; i >= 0; i--)
    13             parent.insertBefore(elems[i], before);
    14     }
    15 
    16     function append(parent, elem) {
    17         var elems = checkElem(elem);
    18         
    19         for(var i = 0; i < elems.length; i++)
    20             parent.appendChild(elems[i]);
    21     }

    然后我们就可以这样调用了append(first(tag('ul')[0]), '<li>Mouse trap.</li>');而之前第二个参数只能是个单独的节点(如<p>,<li>或者textNode);如此一来大大增强了可用性。

    小结的第二部分就到这吧。。测试代码下载

  • 相关阅读:
    CSS媒体查询
    重新认识caniuse
    范仁义css3课程---40、box-sizing属性实例
    前端超级实用技巧---2、css、js兼容性查询网站can i use
    日常英语---200221(shrink)
    心得体悟帖---200221(方针:进可攻退可守的方式:先把不熟悉的知识点录)
    心得体悟帖---200221(本来二月份就到了三月之期的)
    心得体悟帖---200220(对不同的人,用不同的处理方式(这个你远远没有理解))
    java中的String.format使用
    android中的ellipsize设置(省略号的问题)
  • 原文地址:https://www.cnblogs.com/AndyWithPassion/p/professional_js.html
Copyright © 2011-2022 走看看