從原型鏈看DOM--Element類型

来源:http://www.cnblogs.com/venoral/archive/2016/04/02/5338795.html
-Advertisement-
Play Games

Element類型用於表現XML或HTML元素,提供對元素標簽名,子節點及特性的訪問。原型鏈的繼承關係為 某節點元素.__proto__->(HTML某元素Element.prototype)->HTMLElement.prototype->Element.prototype->Node.proto ...


Element類型用於表現XML或HTML元素,提供對元素標簽名,子節點及特性的訪問。原型鏈的繼承關係為 某節點元素.__proto__->(HTML某元素Element.prototype)->HTMLElement.prototype->Element.prototype->Node.prototype->EventTarget.prototype。
以HTML元素為例:document.documentElement.__proto__->HTMLHtmlElement.prototype->HTMLElement.prototype->Element.prototype->Node.prototype->EventTarget.prototype

 

Element節點實例有以下特征:以下特征均繼承自Node.prototype

  • nodeType值為1
  • nodeName值為元素標簽名
  • nodeValue值為null
  • parentNode可能是Document或Element
  • 其子節點可能是Element,Text,Comment,ProcessingInstruction,CDATASection,EntityReference

要訪問元素標簽名,可以用nodeName(繼承自Node.prototype)屬性也可用tagName(繼承自Element.prototype)屬性,這兩個屬性會返回相同的值。但註意返回的字元串是大寫。在HTML中標簽名始終以全部大寫表示,而在XML中(有時也包括XHTML)標簽名則始終會與源碼中的保持一致。假如你不確定自己的腳本將會在HTML還是XML中執行,最好在比較之前進行大小寫轉化。

document.documentElement.tagName;// "HTML"
document.documentElement.nodeName;// "HTML"
document.documentElement.nodeName.toLowerCase();// "html"

 

目錄

  • HTML元素
  • 取得特性
  • 設置特性
  • attributes屬性
  • 創建元素
  • 元素的子節點

 

HTML元素

HTML元素的五種標準特性(ele.attributes[index或'屬性']或ele.getAttributeNode('屬性')得到特性節點),可以取得或修改。
(1).id:繼承自Element.prototype,元素在文檔中唯一的標識符。 document.body.id;// "Posts" 
(2).className:繼承自Element.prototype,與元素的class特性對應,即為元素指定的css類。沒有將這個屬性命名為class,是因為class是ECMAScript的保留字。 document.forms[0].getElementsByTagName('div')[0].className;// "aspNetHidden" 

(3).title:繼承自HTMLElement.prototype。有關元素的附加說明信息,一般通過工具提示條顯示出來。
(4).lang:繼承自HTMLElement.prototype。元素內容的語言代碼, document.documentElement.lang;// "zh-cn" 
(5).dir:繼承自HTMLElement.prototype。語言的方向,值為"ltr"(從左至右)或"rtl"(從右至左)。是規定語言內容的文本方向不是文字順序顛倒。註意一點,應用dir="rtl"後雖然對文本整體是方向性的改變,但對標點符號和文本整體卻做了顛倒。其實很好理解,這個屬性是規定語言的方向,從右向左讀,句號肯定在讀的順序的最後也就是左邊。在換行的時候還是從截斷的文本整體偏向右側。

<div id="myID" class="bd" title="body" lang="en" dir="ltr">...</div>

並不是對所有屬性的修改都能直觀在頁面上表現出來。
對id或lang的修改對用戶而言是透明不可見的;
對title的修改只會在滑鼠移動到這個元素上時才顯示出來;
對dir的修改會在屬性被重寫的那一刻立即影響頁面中文本左右對齊方式;
修改className時,如果新類關聯了與此前不同的CSS樣式那麼就會立即應用該樣式;
關於瞭解所有HTML元素以及與之關聯的原型類型的構造器可參考高程三P263,有的元素是直接繼承自HTMLElement.prototype比如b元素,有的是繼承自HTML某元素Element.prototype,比如a元素,它的原型屬性指向HTMLAnchorElement.prototype。
(6).attributes:繼承自Element.prototype。返回一個NamedNodeMap的實例對象。
這裡擴展瞭解一下NamedNodeMap介面,原型鏈繼承關係為:ele.attributes.__proto__->NamedNodeMap.prototype->Object.prototype。NamedNodeMap介面表示屬性節點對象的集合,儘管NamedNodeMap裡面的對象可以像數組一樣通過索引進行訪問但它和NodeList不一樣,對象的順序沒有指定。NamedNodeMap集合是即時更新的,因此如果它內部包含的對象發生改變的話,該對象會自動更新到最新狀態。

  • length:只讀,返回映射(map)中對象的數量。

  • getNamedItem(str):返回一個給定名字對應的屬性節點(Attr)
  • setNamedItem(attr):替換或添加一個屬性節點到映射map中,會直接反映到DOM中

  • removeNamedItem(str):移除一個屬性節點,也會即時反映到文檔的DOM樹中
  • item(idx):返回指定索引處的屬性節點,當索引超出範圍返回null
  • getNamedItemNS():根據給定命名空間的參數和name返回一個attr對象
  • setNamedItemNS():替換,添加給定命名空間參數和name參數的attr對象
  • removeNamedItemNS():移除給定命名空間參數和name參數的attr對象

 

取得特性

(1).每個元素都有一個或多個特性,這些特性的用途是給相應元素或其內容附加信息。元素繼承自Element.prototype上的三個屬性,它們的功能是操作特性(不是屬性)的方法:

  • setAttribute('attr','value')
  • getAttribute('attr')
  • removeAttribute('attr')

這三個方法都可操作自定義特性,但只有公認的特性才能被應用以屬性的形式添加到DOM對象中,以屬性方式操作這些特性會被同步到html標簽中。HTMLElement的5個特性都有相應屬性(意思是Element.prototype或HTMLElement.prototype上的屬性可直接通過.形式訪問)與其對應:id,title,lang,dir,className。在DOM中以屬性方式操作這幾個特性會同步到html標簽中。因為class特性是這5種特性之一,可以通過className屬性訪問,xsf特性不在Element.prototype或HTMLElement.prototype對象中有對應屬性所以通過屬性訪問方式獲取的值為undefiend。要想訪問xsf特性值可以通過getAttribute('xsf')(推薦)或getAttributeNode('xsf').value或attributes["xsf"].value訪問。

(2).當然元素還能通過繼承HTML某元素Element.prototype上的一些屬性,比如input元素的HTMLInputElement.prototype上的disabled可以通過inputele.disabled取得或設置值。inputele.disabled;// false表示該元素未被設置disabled屬性即未被禁用,inputele.disabled=true;// 表示為該元素設置不可用屬性。

(3).HTML5規範對自定義特性做了增強,只要自定義特性以'data-attrName'形式寫到html標簽中(setAttribute或直接html代碼存在均可),在DOM屬性中就可通過ele.dataset.attrName形式訪問自定義特性。

dataset屬性繼自HTMLElement.prototype,它的值是DOMStringMap的實例集合,原型鏈繼承關係為:ele.dataset.__proto__->DOMStringMap.prototype->Object.prototype。

(4).特性名是不區分大小寫的,getAttribute('id')和getAttribute('ID')都代表同一個特性。
介紹兩個特殊的特性:它們雖然有對應的屬性名,但屬性的值與通過getAttribute()返回的值並不相同。style屬性繼承自HTMLElement.prototype,on事件處理屬性繼承自HTMLElement.prototype或Element.prototype。
(a).style:用於通過css為元素指定樣式。
通過getAttribute()訪問返回的style特性值(在標簽中定義的)中包含CSS文本
通過style屬性訪問返回一個CSSStyleDeclaration類型集合對象,由於style屬性是用於以編程方式訪問訪問元素樣式的因此並沒有直接映射到style特性。該css屬性來自標簽中被設置的style特性。

並沒有background特性值,可以看到不論通過哪個方式獲得的結果都只有元素上style特性設置的屬性才會出現。
通過style屬性返回了一個CSSStyleDeclaration類型實例集合,原型鏈繼承關係為:div.style.__proto__->CSSStyleDeclaration.prototype->Object.prototype

獲得的集合中的屬性只有已設置的才有值,其餘的屬性為空字元串即使它們都有預設值。

簡單學習下CSSStyleDeclaration介面:代表css鍵值對的集合,它在一些API中被使用

  • HTMLele.style 用於操作單個元素的樣式(<ele style="...">)
  • 在getComputedStyle中應用:CSSStyleDeclaration是window.getComputedStyle()返回的只讀介面,其中每個鍵都有值,或被設置的值或預設的值。

ele.style.cssText:聲明塊的文本內容,修改這個屬性會直接將標簽中的style特性內容改變。
ele.style.length:屬性的數量即有具體值的css聲明的數量。window.getComputedStyle()返回值為262。
ele.style.parentRule:包含的CSSRule;
ele.style.getPropertyPriority('attr'):返回可選的優先順序
ele.style.getPropertyValue('attr'):返回屬性值
ele.style.item(idx):返回屬性名,有具體的值的返回屬性名,沒有具體值的返回""
ele.style.removeProperty():刪除的屬性,會直接反映到HTML文檔中元素style特性節點。返回""
ele.style.setProperty('attr','value','priority'):設置屬性,eg: document.body.style.setProperty('color','red','important') 
(b).on事件屬性:以onclick為例,在元素上使用時,onclick特性中包含的是JavaScript代碼,但通過getAttribute()訪問返回相應代碼的字元串。在訪問onclick屬性時會返回一個JavaScript函數(當onclick屬性上不存在函數對象且未在元素標簽中指定相應特性(為什麼說不是屬性是因為如果在ele上沒有找到onclick屬性那就去標簽中找onclick特性值)返回null)。由於存在這些差異,在通過JavaScript以編程方式操作DOM時建議使用onclick屬性值,只有在取得自定義特性值的情況下才通過getAttribute()訪問。
當一個元素標簽中既有onclick特性,同時給ele.onclick指定函數(這操作並不會影響原來標簽中onclick特性的值),則最後只執行ele.onclick屬性的函數。

並且通過getAttribute訪問仍得到的是標簽上的特性值,且即使之前已經給onclick屬性賦值了但控制台顯示元素自身並沒有這個屬性。我不明白為什麼document.body自身上會沒有onclick屬性,那當訪問document.body.onclick時候去哪訪問onclick的值,按著原型鏈嗎?如果函數是在原型鏈上的onclick屬性上也不應該啊HTMLElement.prototype.onclick=function(){console.log(2)}這樣不就使這個方法成共用的了任何HTML元素實例都能訪問,這顯然不實際因為我們只想為某一元素設置某事件函數。對於document.body自身上會沒有onclick屬性不知道是不是JS引擎內部實現的,如果是那具體是怎麼實現的?知道的盆友麻煩告知~

document.body.getAttribute('onclick');// "(function(){console.log(1)})()"
document.body.onclick;// function (){
  console.log(2)
}
document.body.hasOwnProperty('onclick');// false

(c).在<=IE7通過getAttribute()方法訪問style特性和onclick這樣的事件處理程式特性時,返回的值與屬性的值相同。即getAttribute('style')返回的不是字元串而是對象,getAttribute('onclick')返回的不是字元串而是函數。雖然IE8已修複該bug但不同版本的不一致性還是建議使用屬性訪問HTML特性。
一道面試題:下列關於IE,FF下麵腳本的區別描述錯誤的是:感覺這道怪怪的考的是早期支持情況??
A.innerText IE支持,FF不支持  FF早期不支持
B.document.createElement FF支持,IE不支持 X
C.setAttribute('class','styleclass')FF支持,IE不支持   IE早期不支持
D.用setAttribute設置事件FF不支持,IE支持 X
IE:all支持innerText  >IE8支持setAttribute設置特性或事件
FF:新版本支持,舊版本不支持outerHTML outerText innerText;setAttribute支持


設置特性

setAttribute('attr','value'):繼承自Element.prototype。參數為要設置的特性名和值,如果特性已經存在,setAttribute()會以指定值替換現有值,如果特性不存在,setAttribute會創建該屬性並設置相應值。
通過該方法可以操作HTML特性也可以操作自定義特性,通過這個方法設置的特性名會被統一轉換為小寫形式即"ID"轉換為"id"。
因為所有特性都是屬性,所以直接給屬性賦值就可以設置特性的值,但通過添加自定義屬性並不會成為該元素的特性這樣實際上為元素自身添加了屬性。

document.body.id="test";
document.body.getAttribute('id');// "test"
document.body.hasOwnProperty('id');//false

document.body.myid="test";
document.body.getAttribute("myid");// null
document.body.hasOwnProperty('myid');//true

註:<=IE7中,setAtttribute()存在一些異常行為不但通過setAttribute()設置元素基本特性或事件特性沒用而且通過點賦值法設置元素屬性也不會反應到元素標簽中。儘管到IE8才解決這個bug,但還是推薦用點賦值法設置特性。
removeAttribute():繼承自Element.prototype,可以徹底刪除元素特性,不僅會清除特性值還會從元素中完全刪除特性。該方法不常用,但在序列化DOM元素時,可以通過它來確切指定要包含哪些特性。


attributes屬性

Element類型是使用attributes屬性的唯一一個DOM節點類型,attributes屬性繼承自Element.prototype。它的值是NamedNodeMap類型實例,也是個動態集合,元素的每一個特性都由一個Attr類型節點表示,每個節點都保存在NamedNodeMap對象中。

Object.getOwnPropertyNames(NamedNodeMap.prototype);//
["length", "item", "getNamedItem", "getNamedItemNS", 
"setNamedItem", "setNamedItemNS", "removeNamedItem", 
"removeNamedItemNS", "constructor"]

(1).getNamedItem(name):返回nodeName屬性等於name的特性節點。

document.body.attributes.getNamedItem("id");// id="test"
document.body.attributes[0].nodeName;// "id"

(2).removeNamedItem(name):從列表中移除nodeName等於name的節點。該方法與在元素上調用removeAttribute()方法效果相同,直接刪除具有給定名稱的特性節點。這兩種方法唯一的區別就是返回值,removeNamedItem返回被刪除特性的Attr節點。

attrMap.removeNamedItem('style');// style=​"overflow:​ hidden;​"
document.body.removeAttribute('class');// undefined

(3).setNamedItem(attrnode):向列表中添加屬性節點,以節點的nodeName屬性為索引。

var attr=document.createAttribute('class');
attr.value="as";
attr;// class=​"as"
document.body.attributes.setNamedItem(attr);
document.body.attributes;//NamedNodeMap {0: id, 1: style, 2: aria-hidden, 3: class, length: 4}

(4).item(pos):返回位於數字pos位置處的特性節點。 

document.body.attributes.item(3);// class=​"as"

attributes屬性中包含一系列節點,如果想要遍歷元素特性attributes是個很好的選擇。每個節點的nodeName值就是特性節點的名稱,節點的nodeValue值就是特性的值。

document.body.attributes.getNamedItem("id").nodeValue;// "test"
document.body.attributes["id"].nodeValue;// "test"

設置特性的值:先取得特性節點然後將其nodeValue設置為新值。
當你設置document.body.id="test"時候JS引擎內部可能完成瞭如下操作

document.body.id="newid";

transAttr(document.body,'id');
function transAttr(ele,id){
var attrMap=ele.attributes;
for(var i in attrMap){
  if(attrMap.hasOwnProperty(i)){
        if(attrMap[i].nodeName=='id'){
             attrMap[i].nodeValue=ele.id;
       }
    }
 }
 delete document.body.id;
}

在需要將DOM結構序列化為XML或HTML字元串時,多數都會涉及遍歷元素特性。以下代碼展示瞭如何迭代元素的每一個特性然後將它們構造成name="value"這樣的鍵值對形式

function outputAttributes(ele){
   var pairs=new Array(),
         attrName,attrValue,i,len;
   for(i=0;i<ele.attributes.length;i++){
       attrName=ele.attributes[i].nodeName;
       attrValue=ele.attributes[i].nodeValue;
       pairs.push(attrName+"=\""+attrValue+"\"");
   }
  return pairs.join(" ");
}
outputAttributes(document.body);// "id="cd" aria-hidden="true""

這個函數使用了一個數組來保存名值對,最後再以空格分隔符將它們拼接起來(這是序列化長字元串時的常用技巧)。

  • 針對attributes中的特性,不同瀏覽器返回順序不同,這些特性在XML或HTML代碼中出現的先後順序不一定與它們出現在attributes對象中的順序一致。
  • <=IE7會返回HTML元素所有可能特性,包括沒有指定的特性。針對IE7這一bug可以改進一下程式,每個特性節點都有一個specified(繼承自Attr.prototype)的屬性,specified=true表明要麼是在HTML元素中指定了相應特性要麼通過setAttribute()方法設置了該特性。在<=IE7中不論有沒有設置過某特性,某特性都有specified值,但被設置過的值為true,所有未設置過的特性該屬性都為false。在其他瀏覽器中不會為這類特性生成對應的特性節點(因此在這些瀏覽器中任何特性節點的specified值始終為true)
    當並沒有為document.body設置特性節點class
    //<=IE7
    document.body.attributes["class"].specified;// false
    //IE10
    document.body.attributes["class"];// undefiend 

    改進後的代碼為:

    function outputAttributes(ele){
       var pairs=new Array(),
             attrName,attrValue,i,len;
       for(i=0,len=ele.attributes.length;i<len&&ele.attributes[i].specified==true;i++){
           attrName=ele.attributes[i].nodeName;
           attrValue=ele.attributes[i].nodeValue;
           pairs.push(attrName+"=\""+attrValue+"\"")
       }
       return pairs.join(" ");
    }

     

 

創建元素

document.createElement():繼承自Document.prototype,參數為標簽名,這個標簽名在HTML文檔中不區分大小,在XML(包括XHTML)文檔中是區分大小寫的。在使用document.createElement創建新元素的同時,也為新元素設置了ownerDocument(繼承自Node.protoype)屬性,此時還可操作元素的特性為它添加更多子節點以及執行其他操作。

var div=document.createElement('div');
div.id="myNewid";// "myNewid"
div.className="box";// "box"

在新元素上設置這些特性只是給它們賦予了相應信息,由於新元素尚未被添加到文檔樹中,因此設置這些特性不會影響瀏覽器顯示。要把新元素添加到文檔樹中,可使用appendChild(),insertBefore(),replaceChild()均繼承自Node.prototype。一旦將元素添加到文檔樹,瀏覽器就會立即呈現該元素。此後對這個元素所做的任何修改都會實時反映在瀏覽器中。
在<=IE8中以另一種方式使用createElement,即為這個方法傳入完整的元素標簽也可以包含屬性,document.createElement('<div id="test"></div>') 。這種方式有助於避開在IE7及更早版本中動態創建元素(document.createElement('div')然後插入叫動態創建)的某些問題,之前存在以下這些問題:

  • 不能設置動態創建的<iframe>元素的name特性
  • 不能通過表單的reset()方法重設動態創建的<input>元素。
  • 動態創建的type特性值為"reset"的<button>元素重設不了表單。
  • 動態創建的一批name相同的單選按鈕彼此毫無關係,name值相同的一組單選按鈕本來應該用於表示同一選項的不同值,但動態創建的一批這種單選按鈕之間卻沒有這種關係。

上述所有問題都可通過在createElement()中指定完整的HTML標簽來解決。

if(window.navigator.userAgent.search(/MSIE([^;]+)/)){
  //創建一個帶name特性的iframe標簽
 var iframe=document.createElement('<iframe name="myframe"></iframe>');
 //創建input元素
 var input=document.createElement('<input type="checkbox">');
 //創建button元素
 var button=document.createElement('<button type="reset"></button>')
;
 //創建一個單選按鈕
 var radio1=document.createElement('<input type="radio" name="choice" value="one">');
 var radio2=document.createElement('<inpur type="radio" name="choice" value="two">');
}

 

 

元素的子節點

元素的childNodes屬性(繼承自Node.prototype)包含了它所有子節點,這些子節點可能是元素,文本節點,註釋,處理指令。不同瀏覽器在看待這些節點方面存在不同。

<ul id="myList">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>

IE:
IE9~11

IE5~8

Chrome46.0.2490.80:

FF44.0.2 :

如果需要通過childNodes屬性遍歷子節點,通常要先檢查一下當前節點的nodeType屬性。

var ul=document.getElementById('myList');
for(var i=0;i<ul.childNodes.length;i++){
    if(ul.childNodes[i].nodeType==1){
         //do else
    }
}

如果想通過標簽名取得子節點或後代節點,元素也支持getElementsByTagName()(繼承自Element.prototype),返回HTMLCollection類型實例集合是返回當前元素的後代(如果有多層嵌套的話包括子元素和子元素的後代)。document.getElementsByTagName()是繼承自Document.prototype。


參考

《JavaScript高級程式設計》
反本求源——DOM元素的特性與屬性
MDN NamedNodeMap
MDN CSSStyleDeclaration 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • JAVA Quick Java 8 or Java 7 Dev Environments With Docker Printing arrays by hacking the JVM Mobile How to Create a News Reader With React Native: Web ... ...
  • 數量 時間限制:200 ms | 記憶體限制:65535 KB 難度:0 HJS大牛想去街上吃飯,街道旁邊拴著很多狗,他想我堂堂......(省略n個字)豈會被狗咬,所以他很牛的從狗的面前經過,不管是否被上一條狗咬過,下次還會從狗的面前過(J I A N) 現在問題來了,我們給狗編號從1...n,有多 ...
  • 這個星期接到一個新的任務:解決HQ(一個用JAVA開發的開源的運維監控平臺)現在遇到的snmp升級到3.0後bug。公司用的HQ是4.6版本。於是,我把項目從gitlab上clone下來後,就開始了我的填坑之旅。坑了幾天坑,到目前,正常情況,應該只有最後一個坑了,應該是關於tomcat運行環境的。閑 ...
  • 安裝python3.5可能使用的依賴 到python官網找到下載路徑, 用wget下載 解壓tgz包 把python移到/usr/local下麵 刪除舊版本的python依賴 進入python目錄 配置 編譯 make 編譯,安裝 刪除舊的軟鏈接,創建新的軟鏈接到最新的python Enjoy yo ...
  • 頭文件 my_sql.h 實現文件 my_sql.cpp 調用實例 main.cpp ...
  • Atitit.eclipse git使用 1. Git vs svn1 1.1. 直接記錄快照,而非差異比較1 1.2. Git的patch則不依附於branch,commit和commit之間的關係是一個GRAPH3 1.3. hg 本地有更改的時候,可以直接 pull 遠程代碼,然後在自己當前更 ...
  • 首先,我不是一個開發者,只是業餘學習者。其次我的文化水平很低,寫這個主要是記錄一下當前對於這塊的理解,因為對於一個低水平 的業餘學習者來說,忘記是很平常的事,因為接觸、應用的少,現在理解,可能過段時間就會忘了,自己記錄下來應該可以少走些彎路,以免從頭再來查找資料。 另外,如果我的記錄能幫忙到一些朋友 ...
  • 極驗目前的用戶超過7萬家網站,日均驗證量1億次,作為一家專註於驗證安全服務的公司,極驗所要面臨的併發壓力主要表現在以下幾點: 日益增加的用戶併發量。 驗證請求是全動態過程,不能夠進行緩存。 每一次請求都會造成資料庫的讀寫。 處理請求需要耗費CPU大量的時間進行模型的計算。 作為抗擊黑產的第一線,可能 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...