[Rails] 解決 modal update 時 FB plugin (share, like) reload

解決 modal update 時 FB plugin (share, like) reload

目的

  在開發的作品中,每篇貼文都希望能透過 fb share 的功能,達到分享該文資訊和宣傳本作品的作用,所以決定在貼文中加入此一功能,讓使用者在宣傳自己的貼文時,也能夠替我們宣傳!

前言

  凡事與社群網站接軌,有好無壞!

筆記

1. FB plugin

  其實要使用這個功能非常簡單,只要到 facebook developer 按部就班的作,就可以完成此功能。

  在開發 rails 中常遇到 turbolinks 導致 header 中 js 沒有 reload 的問題,我們可以透過一些方法解決:

  • 使用 jquery-turbolinks gem 解決 jquery 部份
  • 而 FB plugin 的解決方法則如下:
    fb_plugin.coffee
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    $ ->
     # 讀取 FB sdk.js
     loadFacebookSDK()
     # 檢查是否 bind 過 fb-root,若否則執行
     bindFacebookEvents() unless window.fbEventsBound
    bindFacebookEvents = ->
     $(document)
      # 將 fb-root detach 起來
      .on('page:fetch', saveFacebookRoot)
      # 放回 fb-root
      .on('page:change', restoreFacebookRoot)
      # 用 FB.XFBML.parse() re-parse all of the XFBML on a page
      .on('page:load', -> FB?.XFBML.parse())
     @fbEventsBound = true
    saveFacebookRoot = ->
     if $('#fb-root').length
      @fbRoot = $('#fb-root').detach()
    restoreFacebookRoot = ->
     if @fbRoot?
      if $('#fb-root').length
       $('#fb-root').replaceWith @fbRoot
      else
       $('body').append @fbRoot
    loadFacebookSDK = ->
     window.fbAsyncInit = initializeFacebookSDK
     $.getScript("//connect.facebook.net/zh_TW/all.js#xfbml=1&version=v2.5")
    initializeFacebookSDK = ->
     FB.init
      appId : 'YOUR_APP_ID'
      status : true
      cookie : true
      xfbml : true

3. Modal(popup) + FB plugin

  然而,我遇到的問題是,當我使用 Bootstrap modal 作文章 preview 時,FB share button 只有在第一次 modal show 會出現,而檢視其他 modal 時並沒有觸發更新,導致 FB plugin 失效了!目前我的解決辦法就是在 modal show 時,利用 FB.XFBML.parse() 刷新,以以上的程式碼為範例,於 $ -> 中加入:

fb_plugin.coffee
1
2
3
4
5
6
7
$ ->
 loadFacebookSDK()
 bindFacebookEvents() unless window.fbEventsBound
 $('#myModal').on 'show.bs.modal', ->
  FB.XFBML.parse()
...

4. 偷吃步?

  當然,如果想快速的達到這個目的,也不用額外寫一支 script,可以在需要用到此 plugin 的頁面直接嵌入 script 就好。

1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
 // 官方 plugin
 (function(d, s, id) {
  var js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) return;
  js = d.createElement(s); js.id = id;
  js.src = "//connect.facebook.net/zh_TW/sdk.js#xfbml=1&version=v2.5";
  fjs.parentNode.insertBefore(js, fjs);
 }(document, 'script', 'facebook-jssdk'));
 // 讀取此頁時直接利用 FB.XFBML.parse() 刷新
 $(FB.XFBML.parse());
</script>

That’s it, DONE!

【參考資料】