整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          聊聊image標簽中處理load事件的那些小經(Ji)驗(Qiao)

          多情況下,我們都需要自己處理image相關的加載邏輯,及其相關的回調函數邏輯,在本文中我將介紹一下javascript中處理相關image標簽,大家嘗嘗會遇到的一些情景,希望對于大家有幫助,當然,如果有大牛能夠提供更好的解決方案和解答,本猿也不盡感謝,OKey,聽我慢慢道來 ~~ ^o^

          情景再現

          大家在開發web應用過程中,往往會有些操作,例如,特定web動畫是需要在某些文件體積比較大的背景圖加載完畢之后才可以觸發滴,所以通常情況下,我們這些程序猿都理所當然的把這些觸發動作放到了img標簽加載的相關load事件處理過程中,jQuery相關代碼參考如下:

          期望行為

          圖片加載完成后,觸發該圖片的load事件,然后觸發callback回調函數中要執行的相關邏輯或者動畫。

          實際情況

          實際場景中,這些比較大的圖片相關的load事件并不是每次都需要被觸發滴,存在偶然性

          解決方案

          以下是一個更新版本的代碼書寫:

          $('#big-image').on('load', function{ // 在回掉函數中執行的一些邏輯 ...... }).each(function{ this.complete && $(this).trigger('load'); });

          相比較前面書寫的相關代碼來說,我們做了一個小小的代碼優化改動,綁定load使用了jQuery中的.one方法而放棄使用.on方法,之所以這么書寫是因為希望load事件在整個代碼邏輯中只被觸發一次,而且避免了被重復執行。

          注意: 如果使用的是 jQuery, 觸發load事件時,我們可以使用.load來觸發,如果你使用的第三方 javascript類庫是zepto的話,那么就只能乖乖使用.trigger('load')方法啦~

          代碼分析

          這里本猿從專業角度和職業角度詳細分析下image的load事件和complete屬性 ^O^

          首先看看MDN的一些load事件文字描述:

          The load event is fired when a resource and its dependent resources have finished loading.

          簡單翻譯過來就是:

          load事件是在一個資源并且該資源的依賴資源都完成加載中之后才被觸發

          這里大家關注一下關鍵字 finished loading,也就是說用戶代理端(例如,瀏覽器/webView)第一次從服務器上請求資源完成,這算finished loading, 當再次刷新這個頁面,如果瀏覽器使用了上次請求的資源(緩存到本地的資源),那就不算做loading, 自然也就不會觸發資源的load事件。當然本猿對于瀏覽器中本地緩存的應用策略沒有深入了解過,這里就暫且不表,待本猿深入研究后再與各位大牛分享一二, 嘿嘿

          complete屬性

          MDN對image元素的complete屬性做了如下的描述:

          HTMLImageElement.complete Read only

          Returns a Boolean that is true if the browser has finished fetching the image, whether successful or not. It also shows true, if the image has no src value.

          簡單翻譯如下:

          HTMLImageElement.complete 只讀屬性
          返回一個boolean值,如果是true的話,說明瀏覽器完成了圖片獲取,無論成功與否。即使這個img元素沒有src屬性值的話,該complete屬性值仍舊顯示為true.

          這個定義的關鍵點在于finished fetching,換個說法,這個屬性只是用來表明瀏覽器是否履行了他的職責(fetch), 與圖片是否能正常顯示并沒有半毛關系(圖片顯示與否是開發者自己的責任),所以同一個頁面進行第二次刷新的時候,如果瀏覽器還記得他已經fetch過這個圖片了(其中一種表現即是瀏覽器緩存了圖片),那么這個屬性值就是true, 否則就是false.

          它跟圖片的load事件沒有直接關系,但是還是有一些間接關系,如果complete值為true話(這種情況一般是非首次加載頁面), 那就表明瀏覽器去抓取過圖片了,那圖片就有可能被緩存,這時load事件就不會觸發,這種情況就需要像如上解決方案中的那樣手動觸發load來輔助實現

          版權說明: 本文配圖/文字版權屬于igeekbar.com及作者聯合所有,如需轉載請務必注明iG客吧原文來源,感謝閱讀支持~

          意: 這篇文章的處理滑塊驗證碼跟平時的不一樣,并不是簡單的一張背景圖,一張滑塊圖計算滑塊的缺口位置。最近由中國音像與數字出版協會舉辦的2020中國游戲十強投票開始,老大問我能不能搞個自動無限投票,我打開網址操作了一番,感覺簡直不要太簡單,直接說這個自動化爬蟲還不是幾分鐘的事情,完全沒什么技術難點呀,分分鐘給他莫的網站投爆。尷尬的是寫到自動化識別滑塊驗證碼的時候。卻發現該滑塊驗證碼是由canvas繪制而成,而不是以往的兩張圖片進行識別。雖然說有點小阻礙。但是想法總比困難多,在我天馬行空的想法下,幾分鐘也就搞定了這個難點。

          目錄

          一、分析網站

          二、canvas滑塊驗證碼

          三、驗證流程


          私信小編01即可獲取大量Python學習資料

          一、分析網站

          • 2020十強游戲投票網址: http://2020top10.cgigc.com.cn
          • 首先發現該網站需要填寫姓名、手機號、郵箱,這...我一頭黑線,網絡上還有這操作去確定一個人的身份真實還是不真實? 中國音像與數字出版協會你可長點心吧,你們技術是爛大街了吧,我都不好意思點破,好歹搞個微信授權登陸呀,這樣就算刷票也只能去買量
          • 我們繼續分析網站,不去糾結人家的技術怎么樣,這里姓名、手機號、郵箱我們都可以自動生成,最關鍵的就是在下一步點擊開始投票的時候,需要驗證滑塊驗證碼

          二、canvas滑塊驗證碼

          ①、背景canvas

          • 我是為了直接展示驗證碼這個環節,所以姓名是瞎寫的,我們自動生成姓名的時候為了真實,一定要以百家姓為基礎去隨機生成
          • 如果想看如何生成隨機姓名、手機號、郵箱請參考: python生成隨機姓名、手機號、郵箱
          • 首先我們看下背景canvas,可以看到dom元素是canvas,這里就尷尬了,跟一般的圖片滑塊驗證碼不一樣,我們如果處理canvas滑塊呢,其實想通了處理起來會比平時的圖片滑塊驗證碼簡單了好幾倍不止
          • 思路肯定是要將canvas的圖片給爬下來,但是很多初學者到這里就尷尬了,他不知道怎么去下載canvas圖片,這個后面會提到,暫時先不贅述

          ②、滑塊canvas

          • 看dom選中的藍色區域,其實就是滑塊canvas,這里可以跟平時僅僅是一張圖片的滑塊有很大不同,可以看出滑塊canvas其實是一張png透明圖片,而這張圖片的大小剛好與背景的大小一摸一樣,這張圖片上繪制了滑塊的正確位置,我們移動滑塊的時候,其實是移動的整張透明的png圖片,當這個圖片與背景重合的時候,透明圖片上的滑塊剛好對應了背景中的滑塊的區域,也就是識別成功
          • 知道了這點,我們就知道為什么會比普通的滑塊驗證碼處理起來更加的簡單,因為普通滑塊需要識別滑塊和背景圖的缺口,但是這個canvas滑塊呢,其實只需要識別透明的滑塊canvas上的滑塊左端距離透明圖片的左端像素是多少,就是需要移動多少距離,這么說可能有點繞,我下面畫個圖理解一下
          • 而且因為他是透明的png圖片,經過顏色反轉之后,只有滑塊的地方有像素,這就更好識別了,直接找到有像素的最小距離即可

          三、驗證流程

          ①、下載滑塊canvas

          def download_yzm(self):
             js = '''
                  return document.getElementById('puzzle-lost').toDataURL()
              '''
              base64str = self.driver.execute_script(js)
              resultstr = base64str.strip("data:image/png;base64")
              resultstr = resultstr[1:]
              imagedata = base64.b64decode(resultstr)
              file = open('./bg.png', "wb")
              file.write(imagedata)
              file.close()
          • 經過上面分析,其實我們不需要管背景,只要處理滑塊canvas即可,首先需要將其下載下來
          • 而學過javascript的小伙伴都知道canvas有個方法toDataURL可以將canvas轉化為base64編碼的格式,我們所需要做的就是將base64的編碼格式保存成最終的png圖片,以供后期識別

          ②、識別滑塊canvas中有像素位置

          def handler_yzm(self, image):
              im = Image.open(image)
              im = im.convert('L')
              w, h = im.size
              result = 0
              for x in range(w):
                  if result != 0:
                      break
                  for y in range(h):
                      if im.getpixel((x, y)) > 0:
                          result = x
                          break
              return result - 10
          • 使用Image模塊處理圖片后,找有像素的最小x軸位置,因為是找x軸,所以從0的位置到圖片最大寬度的位置進行循環,找y軸有像素的最小位置
          • 找到之后,即是滑塊左端距離圖片左端的位置,也就是最終需要滑動的位置,最后結果為啥要減去10個像素呢,是因為分析實際情況,距離差10個像素,看下面紅框的位置

          ③、最后

          • 大家應該都會接下來的自動化操作流程了,希望大家看完后覺得有幫助的,給博主點個關注



          者:linong

          轉發鏈接:https://segmentfault.com/a/1190000022597533


          主站蜘蛛池模板: 亚洲Aⅴ无码一区二区二三区软件| 精品一区二区ww| 人妻av无码一区二区三区| 久久久国产一区二区三区| 一区二区三区四区在线视频| 在线不卡一区二区三区日韩| 一区二区三区在线看| 三上悠亚日韩精品一区在线| 消息称老熟妇乱视频一区二区| 亚洲一区免费视频| chinese国产一区二区| 色久综合网精品一区二区| 亚洲av无码一区二区三区人妖| 无码日韩AV一区二区三区| 中文字幕一区二区三区视频在线| 狠狠爱无码一区二区三区| 中文字幕精品无码一区二区三区| 日本一区二区在线播放| 亚洲国产综合无码一区二区二三区| 国产色综合一区二区三区| 国产小仙女视频一区二区三区| 日本一区二区三区在线观看视频| 日韩有码一区二区| 欧美激情一区二区三区成人| 国产人妖在线观看一区二区| 乱码人妻一区二区三区| 中文字幕一区二区精品区| 一级毛片完整版免费播放一区 | 武侠古典一区二区三区中文| 色婷婷一区二区三区四区成人网| 精品日韩在线视频一区二区三区| 亚洲av永久无码一区二区三区| 99精品国产一区二区三区不卡| а天堂中文最新一区二区三区| 乱色熟女综合一区二区三区| 视频在线观看一区二区| 国产一区二区免费在线| | 综合无码一区二区三区| 中文字幕乱码人妻一区二区三区| 91精品国产一区二区三区左线|