1. 程式人生 > >前端基本功之從大型專案中迅速定位修改位置

前端基本功之從大型專案中迅速定位修改位置

前端開發,有一項很重要的基本功,就是在大型專案中,比如幾萬行js程式碼中,迅速找到新增功能或除錯bug的切入點。特別是你只是接手這個專案,並不瞭解其中每一個功能點所在的位置,也沒有時間一行行讀程式碼的情況,這個基本功顯得尤其重要。 

這項能力除了嫻熟的除錯工具使用技巧,更重要的還是對變化的觀察力和總結歸納的能力。本文用一個講一個功能案例的實現。

功能背景

一款大型canvas應用。我們使用了一些開源庫實現canvas上的文字與html文字的互轉。使我們可以在一個輸入框中輸入文字然後繪製到canvas上去。也可以點選canvas上的文字然後通過開源庫進行文字編輯。

要實現功能

我們的canvas應用有整體放大縮小的功能。但是文字輸入與我們的canvas應用是兩個不同的體系,現在我們要對這個文字輸入相關的庫進行對應的放大縮小的調整。在canvas應用處於放大縮小的場景,text輸入框對應放大縮小。並且在放大縮小的場景下對輸入框中的字型的放大縮小,在迴歸到正常大小的時候。顯示與100%時設定的字型大小相同。

目前的情況是應用處於放大狀態時,輸入內容以及轉化到canvas上的大小依然是畫布100%時的大小。然後當畫布變回正常大小,之前繪製到canvas上的的文字就小的沒法看了。

canvas應用放到大300%時文字元件的情況:
canvas應用放到大300%時文字元件的情況

canvas應用放到大300%時繪製到canvas上的文字:
原始效果

canvas應用回到正常100%時繪製到canvas上的文字情況:
原始效果

實現

首先觀察輸入框的大小什麼決定。要先觀察輸入框的組成結構。檢視elements,發現它是dom結構,沒有在iframe中,也不是canvas繪製,先鬆一口氣,看來僅僅是dom上的變換。
dom結構
然後我們在輸入框中輸入,同時觀察右邊dom結構有什麼變化。發現輸入到第二個字元的時候多了一個帶內聯屬性的font-size的span,我們輸入的內定到這個span標籤中。
span標籤


然後通過輸入元件的工具欄把輸入的字型調整到其他字號。發現內聯的font-size有變化。字型變大。輸入框變大。

猜測輸入框大小跟這個字號有關係。

在不同的縮放比例下,按照我們的縮放比例乘以100%狀態下的的字型大小。就是在該比例下的大小了。

首先看span是怎麼加入進去的,監聽p的子節點變化。加一個dom斷點。
監聽p
監聽到了appendChild。然後檢視呼叫棧。
斷點
定位到這個位置,看到是在這裡給span設定了14px的預設大小,修改它:
斷點

var scaleValue = $("#zoomIn-container").attr('data-float')||1;
me.mark('fontsize'
, 14*scaleValue);

重新整理,發現開啟輸入框,輸入框大小跟之前一樣,輸入第一個字時還跟之前一樣,輸入第二個字母,span出來之後,字型和輸入框就變成當前比例下我們想要的大小了。
效果
另外,發現那句程式碼有一句註釋 16 to 14。
猜測之前有一次預設字型大小從16到14的整體改動。如果我們全域性搜尋一下16 to 14這個改動,也許會有意想不到的發現。

那麼第一個字母的大小由什麼決定?用chrome一看,由css決定。父元素的font-size決定。所以現在我們父元素的css要動態修改。在初始化輸入框的時候就要設定好內聯的css。如何知道在哪裡初始化的文字dom,哪裡改?

觀察,發現輸入框消失之後,整個輸入框相關的節點都消失了。猜測整個輸入相關的節點由js動態生成。於是全域性搜尋class名。

果然搜到,然後在dom初始化之後的程式碼中加入以下程式碼,設定字型大小。

// ls20180523 把傳入的字型大小。根據當前比例做一個縮放。
var scaleValue = $("#zoomIn-container").attr('data-float') || 1;
$container.find(id).css('font-size',14*scaleValue);

重新整理。初始框變大。第一個字母變大。繼續輸入字型依然變大。
斷點
然而輸入第一個字母,點出去,發現繪製到canvas上的依然是100%狀態下的14px。而輸入多個字元的時候,字型是該比例下的大小。因為上面的觀察我們知道只有一個字母的時候是沒有span生成的,所以可能對產生的canvas字型有影響。 那麼我們txt轉canvas的函式可能也需要修改。

這個函式在哪裡?是不是有這樣一個函式?有什麼辦法知道?由前面的觀察我們發現點出去的時候文字元件相關dom是會消失的。於是,斷點它。
斷點
在呼叫棧裡發現這樣一個函式。果斷進去看一看。
斷點
然後在這個函式裡設定斷點。重新操作,在裡面一步步走一下。
很容易地,我們找到這個函式,並最終定位到這行程式碼。修改之。
定位

//ls20180524 根據縮放比例調整。
var scaleValue = $("#zoomIn-container").attr('data-float')||1;
result = '<p><span style="font-size: ' + 14 * scaleValue + 'px; font-family: arial; color: rgb(0, 0, 0);">' + matchTarget[1] + '</span></p>';

再測試。發現只輸入一個字。到canvas上大小正確。

然而出現了新的問題。如圖。這個字號設定的地方。顯示變成了我們實際的大小值。實際應該顯示的是我們dom上設定的大小值除以當前頁面比例的值,才是我們100%比例時候的值。我們要找到它在哪裡修改的。觀察這個節點是何時從14變成這個值的。然後設定斷點觀察節點變動。到這個賦值的地方給值進行一個換算就可以了。
另一個問題
然後剩下最後一個功能。修改字號。修改字號後我們框裡的字型大小應該是縮放後的比例下的這個字號的大小。只要監測相關節點的變動,然後切換一下字號,就可以找到設定span大小的節點。都很好修改了。

到這裡這個功能就基本完成,哪怕是一個剛接手的專案,整個功能修改過程也不超過2小時。當然,後續還有問題要考慮,比如高分屏裝置畫素比的問題。
修改後,canvas應用放大300%時的字型元件:
完成後效果圖

總結

到這我們就基本實現了我們的功能,程式碼量很小。要注意修改其他人程式碼的時候,要考慮修改的地方的方法的作用,使用範圍等。儘量保證自已寫的東西不會影響到其他可能的邏輯,要從程式碼編寫者的角度進行多方面的思考。對於第三方庫的使用,我們首先要考慮庫原有介面的組合使用,在原有介面不足的情況下才考慮修改原始碼。

通過觀察分析和斷點技巧,我們很容易地就從一個大型專案幾萬行程式碼中迅速定位到我們要修改的地方。