zeroclipboard / zeroclipboard-rails

ZeroClipboard rails gem
http://zeroclipboard.org/
MIT License
125 stars 36 forks source link

It does not work well with turbolinks #11

Closed junwchina closed 10 years ago

junwchina commented 10 years ago

When I redirect to other page and redirect back then. It dose not work any more.

Uncaught TypeError: Object # has no method 'setSize'

JamesMGreene commented 10 years ago

Hmm, makes sense but is troublesome. It would be happening because the JS is loaded and is still actively loaded after a Turbolinks transition; conversely, the Flash movie was embedded in the body, which Turbolinks then switches out wholesale (thus removing the Flash movie, which does not stay in memory).

Does Turbolinks expose any hooks for JavaScript callbacks before/after transitions? If so, perhaps you could reset the JS's state tracking of the Flash movie so that it understands it's not loaded anymore, or temporarily hold the movie DOM element in JS memory and then re-append it to the DOM after the transition...?

I'm not guaranteeing that either of those will work for sure as-is but they're valid ideas on the direction to take this bug.

Probably why GitHub uses PJAX for more granular/selective transitions.

JamesMGreene commented 10 years ago

P.S. And, unfortunately, object elements cannot be reliably added to the head instead. Some older browsers used to allow it but this was explicitly forbidden in HTML5.

junwchina commented 10 years ago

Thanks. Fixed it by reload javascript file. The file path is /public/assets/ZeroClipboard.min.js.

$(document).on('page:load ready', function(){
  $.getScript('/assets/ZeroClipboard.min.js', function() {
      console.log("loaded ZeroClipboard")
    });
});
JamesMGreene commented 10 years ago

Cool, glad you could find a workaround based on the info I provided.

@HaNdTriX @myitcv: Anything we can do about this from the Gem's perspective? I'm guessing not but I'm not very familiar with the guts of the Rails Asset Pipeline nor Turbolinks.

junwchina commented 10 years ago

Maybe you can implement this library in jQuery, and do initialize in jQuery.ready callback. That would be compatibility with turbolinks with jQuery.turbolinks.

JamesMGreene commented 10 years ago

The primary library definitely won't be written as a jQuery plugin, though it would be nice to bring jquery.zclip back to life to provide a jQuery wrapper. That said, if it's as easy as just using jQuery.ready, it seems like this is an easy workaround for the subset of folks out there that are using both ZeroClipboard and Turbolinks together.

HaNdTriX commented 10 years ago

@junwchina Did you try these workarounds?:

Pure Javascript Workaround

// The page has been parsed and changed to the new version and on DOMContentLoaded
document.addEventListener("page:change", function(){
  // initialize ZeroClipboard here
  var zeroClipboard = new ZeroClipboard(...);
});

// A Turbolinks-enabled link has been clicked 
document.addEventListener("page:before-change", function(){
  ZeroClipboard.destroy();
});

@see https://github.com/zeroclipboard/zeroclipboard-rails/issues/7

JQuery Workaround

// The page has been parsed and changed to the new version and on DOMContentLoaded
$(document).on("page:change", function(){
  // initialize ZeroClipboard here
  var zeroClipboard = new ZeroClipboard(...);
});

// A Turbolinks-enabled link has been clicked 
$(document).on("page:before-change", function(){
  ZeroClipboard.destroy();
});

@see https://github.com/zeroclipboard/zeroclipboard/issues/54 @see https://github.com/rails/turbolinks/ for custom events

junwchina commented 10 years ago

@HaNdTriX I did not get a try. But i think the way you provided should work as well.

When you use turbolinks, you will have to trigger jQuery.ready(i thought you were using jQuery) to re-bind your events after loading a page. That is just the jQuery.turbolinks did. So If we do initialize in jQuery.ready callbacks, we don't need other process on it any more.

@JamesMGreene It would be nice to provide a jQuery wrapper. The simplest way is just wraps this library in jQuery like this.

$(function(){
    //ZeroClipboard Javascript codes here
    // Pure javascript is fine
})
junwchina commented 10 years ago

On the gem perspective, I think maybe it's better to have a ZeroClipboard.js and a jQuery.ZeroClipboard.js. Developer can choose which one to use in their project. When I am using turbolinks, i would like to have jQuery.ZeroClipboard.js on my project.

Anyway, this library is very cool. Thanks you guys.

myitcv commented 10 years ago

@junwchina - I agree so I think we can close this issue. Please re-open if you disagree

JamesMGreene commented 10 years ago

@myitcv I'm a bit lost in this Rails/Turbolinks thread. Can you clarify what you are agreeing with @junwchina on and if there are additional follow-up steps? Thanks!

myitcv commented 10 years ago

@JamesMGreene - definitely nothing to do from the zeroclipboard perspective. But I think we can and should include some documentation in zeroclipboard-rails on how to get up and running when using Turbolinks (which is the default under 4.0.x). I'll reopen until that is done.

myitcv commented 10 years ago

@HaNdTriX - do you have a reference you could refer to and write up a short piece on for how to handle Turbolinks?

anhkhoi commented 10 years ago

@HaNdTriX, thank for your workaround, it's working for me

HaNdTriX commented 10 years ago

@anhkhoi thanks for letting me know.

Actually I don't think this is an zeroclipboard issue. The issue is based on the architecture of turbolinks thats why I am closing this issue.