d3.js(v5.7)的attr()函數完善(添加obj支持)


因為習慣了jquery的attr(obj)批量添加屬性,所以剛開始看到d3為dom添加屬性要一個一個添加的時候真的是十分想吐槽,既然想實現attr(obj),根據傳入對象的鍵值對批量添加dom屬性,那就得改它的源碼了。

因為看d3的dom是這樣選擇的:

d3.selectAll("h1");

那么直接打印這個,控制台顯示的是一個Selection對象,如圖:

image.png

並且獲得這個節點之后,是可以直接通過attr()來為dom添加屬性的,那么我們就來看d3下的selection,控制台console.log(d3):

image.png

果不其然,d3下有個selection對象,selection對象下有attr()這個原型方法;

此時,我就想了干脆直接重寫d3.selection.prototype.attr()這個方法,於是一頓操作猛如虎,寫下了如下代碼:

image.png

然后:

image.png

一看頁面,沒反應(其實這里由於d3的dom處理規則問題導致我這句代碼是有問題的,稍后會講解)

那怎么辦呢,直接看他attr的源碼吧:

image.png

打開之后:

image.png

我們看他這個對外暴露的方法:

首先他通過this.node()獲取dom對象,所以之前我重寫的方法里面的this拿到的是d3獲取的selection對象,需要將其轉為DOM對象;

然后d3的這個方法里面,判斷參數個數小於2的時候(那就是1咯),執行getter方法獲取屬性值,這個沒有異議;

針對setter,為了支持對象型參數,並實現批量添加屬性

於是,添加了如下代碼:

image.png

然后,驗證一下(為h1添加兩個屬性):

image.png

image.png

結果只有第一個獲得了兩個屬性,一方面驗證我之前添加的代碼是沒有問題的,一方面驗證selectAll()並不能不會循環執行后續操作,但想到之前綁定數據之后的text()是可以實現循環賦值的,那么:

image.png

image.png


至此,便可以愉快地批量添加屬性了。不用像網上教程那樣,千篇一律的多重attr()操作:

image.png


但是!重點來了,以上簡單的修改,不難發現只支持字符串型屬性值,d3可是支持函數型屬性值得啊,不用怕,后續我也針對函數型屬性值作了補充:

image.png

頁面使用:

image.png

頁面展示:

image.png

至此,這個函數應該算是比較完善了,反正我用得挺順手

注:

我們現在的HTML都是通過DOCTYPE來聲明,XHTML中有xmlns聲明,svg標簽也是有的,d3中有刪除通過命名空間和名稱指定的屬性的方法,但是我們現在寫的時候,都不需要添加命名空間,所以我修改的方法就沒有添加removeAttributeNS()支持了,最終版:

image.png


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM