Giter Club home page Giter Club logo

jquery.turbolinks's Introduction

โš ๏ธ Deprecated โš ๏ธ

This gem does not work with Turbolinks 5+, and is not compatible with many jQuery plugins. We do not recommend using it. Instead, please consider writing your JavaScript in a way that makes it compatible with Turbolinks. These resources can help:

  • RSJS - A reasonable structure for JS, a document outlining how to write JavaScript as "behaviors" that will be compatible with Turbolinks.

  • onmount - 1kb library to run something when a DOM element appears and when it exits.

Rationale: making jQuery plugins compatible with Turbolinks requires more than simply dropping in a library. It should be able to setup and teardown its changes as needed, which is something you can't automate. jQuery Turbolinks's approach worked well enough for many libraries back in 2013, but today this is no longer the case. Given its utility is very limited, we've decided to no longer maintain this library.


jQuery Turbolinks

Build Status

Do you like Turbolinks? It's easy and fast way to improve user experience of surfing on your website.

But if you have a large codebase with lots of $(el).bind(...) Turbolinks will surprise you. Most part of your JavaScripts will stop working in usual way. It's because the nodes on which you bind events no longer exist.

I wrote jquery.turbolinks to solve this problem in my project. It's easy to use: just require it immediately after jquery.js. Your other scripts should be loaded after jquery.turbolinks.js, and turbolinks.js should be after your other scripts.

Initially sponsored by Evil Martians.

This project is a member of the OSS Manifesto.

Important

This readme points to the latest version (v2.x) of jQuery Turbolinks, which features new 2.0 API. For older versions, see v1.0.0rc2 README.

Usage

Gemfile:

gem 'jquery-turbolinks'

Add it to your JavaScript manifest file, in this order:

//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//
// ... your other scripts here ...
//
//= require turbolinks

And it just works!

Checkout "Faster page loads with Turbolinks" for deeper explanation how to use jQuery Turbolink in real world.

API and Customization

$.turbo.use

By default, jQuery.Turbolinks is bound to page:load and page:fetch. To use different events (say, if you're not using Turbolinks), use:

$.turbo.use('pjax:start', 'pjax:end');

$.turbo.isReady

You can check if the page is ready by checking $.turbo.isReady, which will be either true or false depending on whether the page is loading.

Troubleshooting

Events firing twice or more

If you find that some events are being fired multiple times after using jQuery Turbolinks, you may have been binding your document events inside a $(function()) block. For instance, this example below can be a common occurrence and should be avoided:

/* BAD: don't bind 'document' events while inside $()! */
$(function() {
  $(document).on('click', 'button', function() { ... })
});

You should be binding your events outside a $(function()) block. This will ensure that your events will only ever be bound once.

/* Good: events are bound outside a $() wrapper. */
$(document).on('click', 'button', function() { ... })

Not working with $(document).on('ready')

jQuery Turbolinks doesn't support ready events bound via $(document).on('ready', function). Instead, use $(document).ready(function) or $(function).

// BAD: this will not work.
$(document).on('ready', function () { /* ... */ });

// OK: these two are guaranteed to work.
$(document).ready(function () { /* ... */ });
$(function () { /* ... */ });

Changelog

This project uses Semantic Versioning for release numbering.

For changelog notes, checkout releases page.

Contributors

Initial idea and code by @kossnocorp, with special thanks to @rstacruz and other the project's contributors.

License

The MIT License

Bitdeli Badge

jquery.turbolinks's People

Contributors

anayden avatar bitdeli-chef avatar davydotcom avatar jmccartie avatar josepjaume avatar kossnocorp avatar neilsarkar avatar rstacruz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jquery.turbolinks's Issues

jquery.turbolinks does not work with Foundation 2.x

I have a rails project using zurb foundation 2.x. I just tried your gem hoping that all will be working as foundation uses $.ready() function. But instead it breaks on the customforms plugin:

TypeError: $ is undefined
$.foundation.customForms.appendCustomMarkup = function () 

So is it a problem with jquery.turbolinks or zurb foundation?

Does not work out of the box

created new rails project using ruby version 2.2.2

in Gemfile
...
gem 'rails', '4.2.4'
...
gem 'jquery-turbolinks'

$ bundle install
....
Using turbolinks 2.5.3
Using jquery-turbolinks 2.1.0

in application.js
//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require turbolinks
//= require_tree .

when running app / loading page
couldn't find file 'turbolinks' with type 'application/javascript'
//= require turbolinks << pointing to this line

Does not work with $(document).on('ready')

I used this:

$(document).on('ready', function() {
  ...
});

and my callback wasn't being called by jquery.turbolinks when I clicked a link and it went through Turbolinks.

I had to change it to $(function() {}) or $(document).ready(function() {}); for it to work. I know those syntaxes are more common. But since there are so many references to $(document).on in places that talk about Turbolinks (including $(document).on('ready page:change') when not using jquery.turbolinks), other people might use it too, as I did.

jQuery 1.11.0
Turbolinks 2.2.2

Customization history.state

Hi, I have a problem

I want to store #main-container(overflow:scroll)'s scrollTop,
that when I click browser's back button, I can use it to set scrollTop.

But, I find I can't write anything in history.state, it will rewrite by turbolinks

> history.state.scrollTop = 200`
< Object {turbolinks: true, url: "http://localhost:3000/",scrollTop:200} 

change page and back

> history.state
< Object {turbolinks: true, url: "http://localhost:3000/"} 

I had to use localStorage

      $(document).on('page:before-change', function(){
        localStorage[location.pathname] = $('.main-container').scrollTop();
      })
      $(document).on('page:change', function(e){
        $('.main-container').scrollTop(localStorage[location.pathname])
      })

how cant I use history.state to do this ?

Test on Node v0.10 in Travis

No need to test on antique v0.4 and v0.6... in fact, it causes more problems than its worth:

ReferenceError: Uint8ClampedArray is not defined
    at Object.createWindow (/home/travis/build/kossnocorp/jquery.turbolinks/node_modules/jsdom/lib/jsdom/browser/index.js:300:24)
    at Object.windowAugmentation

Callbacks get duplicated when a page is visited multiple times

There's two pages that link to each other. Let's call them Page A and Page B.

Page A looks like;

<a href="pageb">page b</a>

And page B looks like:

<a href="pagea">page a</a>
<script type="text/javascript">
 $(document).ready(function() {
    console.log(window.location.href)
  });
</script>

Start on page A, and navigate to page B; the page's URL will be logged once. Navigate back to page A, and the URL will be logged again. Navigate back to page B, and it will be logged twice. Basically, an additional .ready() handler will be added each time, so after a while you might find the events from page B being run 10 times each time you go from one page to the other.

It's late at night so I haven't been able to think of an elegant solution. But I imagine that checking for duplicates at line 35 (https://github.com/kossnocorp/jquery.turbolinks/blob/master/src/jquery.turbolinks.coffee#L35) would work. Every .ready() callback should only be called once per page:load, I think.

I doubt it makes a difference, but I'm using Chrome 23 on OS X.

Secondary issue;

In my project, the initial issue came up because I have some object initialisation that only happens on one particular page;

<script type="text/javascript">
 $(document).ready(function() {
    window.handler = new Handler().init();
  });
</script>

So I'll have to modify the init() function to only act if it's on the right page. Unless this project could somehow solve that problem too?

Issue with rails_ujs

Delete link (data-method=delete data-confirm="Yes?") + rails ujs + turbolink'd page (after page change) = fail
Likely related to how rails_ujs binds events

event being fired 3x even with correct js

I have this JS on my app

$(document).on('page:before-change', function(){
  if($('.chat-text-field').val())
    return confirm("Your message hasn't been sent yet. Do you still want to leave?");
});

turns out that this message is beign fired 3 times. Is there something else missing?
Also, my data-confirm message are being fired multiple times.
I'm using Ruby 2.2.2 with Rails 4.2.3 and Turbolinks 2.5.3

foundation + rails 4 + Readme recommendation disables turbolinks

Getting a //= require turbolinks in the resulting application.js which implies Sprockets stopped processing requires.

An easy fix is to drop the snippet into app/assets/javascripts/foundation.turbolinks.js and //= require foundation.turbolinks in application.js

Update vendor JS

Hi!
I think the js in the vendor folder are for version 2.0.0. You might want to update them.

Thanks!

If I define events outside jQuery.ready(), how do I access functions defined inside the jQuery wrapper

/* Good: events are bound outside a $() wrapper. */
$(document).on('click', 'button', function() { ... })

While I like this style, (becuase it gaurantees events won't be bound twice,
How can I reference functions that have been defined inside my jQuery.ready()
block from outside the block?

Or are you saying, do away with jQuery.ready() all together and just define all functions and events outside the jQuery.ready block?

Not working with Foundation 5?

I don't know if you've come across this problem before. But, most of the components that power Foundation 5 button elements aren't transitioning including the tabs. Maybe, you can help me get the JavaScript to initialize so, that I can move on with production of my app. Thank you!

Multiple delegates

Hi,

I have a conceptual question.

With code like:

$(document).on(event, selector, handler)

handler delegates to selector multiply times. I wonder if it s a good idea to remove all delegates on page:load?

Currently I need to do $(document).off(event, selector) each time.

Assets requested even on enabling turbolinks

I am using jquery.turbolinks with rails 4 + coffee script.

  1. How do I verify if turbolinks is loading the page on click ? How do I verify this
  2. Does loading via jquery.turbolinks request assets even if the sequence is same ? I noticed that the railscasts screencast on turbolinks displays that it does not load assets
  3. Can I verify this in development mode or do I need to compile the assets in order to see this in action ?

Article on Turbolinks

Here's an opinionated article on how to properly use Turbolinks:

https://coderwall.com/p/ypzfdw

it may be cool to link this on the Readme. However, considering who the author is (heh), I'd like to hear some outside validation on whether it should be linked from the Readme or not.

(cc @kossnocorp)

browser back button

this is a great plugin, it fixed most of my issues but 1.

When you use browser back button no events are fired.

Doesn't handle jQuery(fn)

jQuery 1.8.2 source code:

// HANDLE: $(function)
// Shortcut for document ready
} else if ( jQuery.isFunction( selector ) ) {
    return rootjQuery.ready( selector );
}    

So, it's using rootjQuery for that internally (which doesn't have a modified .ready), and the callback never gets registered with our callbacks

bad ideas for a fix:

  • Override jQuery(function)
  • Override the promise object

Events firing twice or more

I read troubleshooting section but I got this problem:

;(function(App){

    App.Supertestes = {};

    App.Supertestes.bindFunctions = function() {

        console.log('bind called');
        $(document).on("click", '.bt_login', function(e){

            console.log('.bt_login clicked');
            return false;
        });

    };


    App.Supertestes.init = function() {
        this.bindFunctions();
    }

})(App);

$(document).ready(function(){
  App.Supertestes.init();
});

I'm using the gem but the event is trigged twice or more. What is wrong? Do use the listeners inside App object is wrong?

Gem does not work

Hi!
I found this gem and thought it would be nice to use in my project.
But unfortunately it does not work for me.

Here is my application.js

//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs

//= require ...
//= require ...

//= require turbolinks

I have

rails (4.2.6)
jquery-rails (4.1.1)
jquery-turbolinks (2.1.0)
turbolinks (5.0.0)

Am I doing something wrong?
Thank you.

Attaching a handler to the window scroll event run on all pages

When I attach a handler to the window scroll event on one specific page, this handler is executed on every following page I visit.

For example (see code below). When I visit page 'foo' and start scrolling I see that I'm 'scrolling in foo'. If I then click on the link to visit the 'bar' page and start scrolling, I see the same message.

Is this my bad or is this an issue with Turbolinks?

foo.html.erb:

<%= link_to "Go to bar", bar_path %>
<div id="output">...</div>
<script>
  $(window).on('scroll', function() {
    $("#output").text("scrolling in foo");
  });
</script>

bar.html.erb:

<%= link_to "Go to foo", foo_path %>
<div id="output">...</div>

turbolink

when i click the back button in browser, turbolinks loads twice. how to solve this problem

Undefined method `environment` for nil:NilClass

After installing this gem I received the flowing error:

undefined method `environment' for nil:NilClass

Which links to framework_and_overrides.css.scss! I tried removing the gem without any changes to other files and everything works fine again. I was unable to debug this problem but the error is raised during stylesheets import on this line:

<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => "true"   %>

jquery-turbolinkserror

Inconsistent behavior

There's currently inconsistency in the "isReady" / not states.
Consider this part of (the compiled javascript):

      if ($.turbo.isReady) {
        return callback($);
      } else {
        return $document.on('turbo:ready', function() {
          return callback($);
        });
      }

When it's ready, then the callback is executed only once (right away), and if it's not, then the callback is added on 'turbo:ready' for ever. I propose to change the "on()" to "one()" for consistency.

P.S. I found that while doing performance analysis of our application, and found multiple invocations of the "onready" callback.

elixir webpack fix [Module not found]

Hello there, I found that by default webpack doesn't find jquery.turbolinks module but if you add this:

"main": "vendor/assets/javascripts/jquery.turbolinks.js",

after

"license": "MIT",

at package.json file, it will work perfectly!

Error in jQuery document ready handler in Rails 4

This worked fine in Rails 3.2. I'm updating to Rails 4 and experiencing an error in my document ready handlers. If I remove jquery.turbolinks from my application.js, the error goes away.

behavior.js is a file with a declaration like this:

jQuery(function($) {
  $('form').submit(function(){
  ...
  });
});

On page load, I get the following error:

Uncaught TypeError: object is not a function behavior.js?body=1:2
(anonymous function) behavior.js?body=1:2
jQuery.event.dispatch jquery.js?body=1:5096
elemData.handle jquery.js?body=1:4767
jQuery.event.trigger jquery.js?body=1:5008
(anonymous function) jquery.js?body=1:5692
jQuery.extend.each jquery.js?body=1:658
jQuery.fn.jQuery.each jquery.js?body=1:267
jQuery.fn.extend.trigger jquery.js?body=1:5691
$.turbo.onLoad jquery.turbolinks.js?body=1:33
fire jquery.js?body=1:3049
self.fireWith jquery.js?body=1:3161
jQuery.extend.ready jquery.js?body=1:434
completed jquery.js?body=1:105

Cannot resolve file jquery.turbolinks

  1. This is my application.js:
    //= require jquery
    //= require jquery.turbolinks
    //= require jquery_ujs
    ...
    //= require turbolinks

  2. I've added the following to the Gemfile:
    gem 'jquery-turbolinks'

  3. I ran bundle install.

RESULT
In my application.js the jquery.turbolinks line is marked with a warning (CANNOT RESOLVE FILE JQUERY.TURBOLINKS)... it's strange because it's the only one with this issue. Note that i'm using RubyMine IDE (i don't know if it could help).

on Click event being fired multiple times

I have added jquery.turbolinks gem in my rails application and have bind my button like this

<script> $(document).on('click', '.tmp', function() { }); </script>

this click is being fired multiple times don't know why

Javascript plugins not working properly with turbolinks

I'm using share buttons (javascript plugins). When I open a page it shows that buttons, but when I open other page it disappear. It appear again when i refresh website. It working properly with jquery.turbolinks and without turbolinks gem, but without it website is very slow. How to make website faster? My website, now plugins is working, because I removed turbolinks.

application.js

//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require lightbox
//= require_tree .
//= require turbolinks

application.html.erb javascript plugins

<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-588e44a9401a6d9f"></script>
<script type="text/javascript" id="st_insights_js" src="http://w.sharethis.com/button/buttons.js?publisher=630cdfb3-b6c5-4da7-a389-1c7d5340827d"></script>
<script type="text/javascript">stLight.options({publisher: "630cdfb3-b6c5-4da7-a389-1c7d5340827d", doNotHash: false, doNotCopy: false, hashAddressBar: false});</script>

Gemfile

gem 'jquery-turbolinks'
gem 'turbolinks', '~> 5.0.1'

I tried to add one plugin in javascript file, but result same

$(document).on('turbolinks:load', function(){
  stLight.options({publisher: "630cdfb3-b6c5-4da7-a389-1c7d5340827d",      doNotHash: false, doNotCopy: false, hashAddressBar: false});
});

Thank you for any help.

jquery.turbolinks file not found

After following all the instructions i am getting this error
"Sprockets::FileNotFound in StaticPages#home
Showing /home/abhinay/rails_projects/sample_app/app/views/layouts/application.html.erb where line #9 raised:

couldn't find file 'jquery.turbolinks'
(in /home/abhinay/rails_projects/sample_app/app/assets/javascripts/application.js:16)
screenshot from 2013-10-17 21 38 49
"
can you please tell me what is Happening here.

JQuery: "Uncaught TypeError: Cannot read property 'length' of undefined"

Adding jquery.turbolinks causes JQuery itself to crash, saying "Uncaught TypeError: Cannot read property 'length' of undefined"

My application.js:

//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require angular/angular.min
//= require angular/angular-route.min
//= require jquery-ui.min
//= require chosen-jquery
//= require bootstrap
//= require conversations
//= require analytics
//= require common
//= require jquery.infinite-pages
//= require jquery.contenthover
//= require overlay
//= require tag-it.min
//= require_tree .
//= require_tree ../../../vendor/assets/javascripts/.
//= require turbolinks

The function in question where it crashes:

merge: function( first, second ) {
    var len = +second.length,
        j = 0,
        i = first.length;

    while ( j < len ) {
        first[ i++ ] = second[ j++ ];
    }

    // Support: IE<9
    // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
    if ( len !== len ) {
        while ( second[j] !== undefined ) {
            first[ i++ ] = second[ j++ ];
        }
    }

    first.length = i;

    return first;

When the page has already loaded

If the page has already loaded, when a callback is added, it should be triggered immediately
This is jQuery behaviour, but is not jquery.turbolinks behaviour

Try running this with / without jquery.turbolinks:

$ -> console.log('triggered') 

Not working with Twitter Boostrap 3 for affix, etc.

The Affix plugin launches for any element that has data-spy="affix" but this is not getting launched after navigation to a page.

Currently have:

//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require bootstrap
//= require underscore.1.6.0
//= require backbone.1.1.2
//= require_tree ./models
//= require_tree ./collections
//= require_tree ./views
//= require_tree ./routers
//= require_tree ../templates
//= require turbolinks

The Affix plugin has:

// AFFIX DATA-API
  // ==============

  $(window).on('load', function () {
    $('[data-spy="affix"]').each(function () {
      var $spy = $(this)
      var data = $spy.data()

      data.offset = data.offset || {}

      if (data.offsetBottom) data.offset.bottom = data.offsetBottom
      if (data.offsetTop)    data.offset.top    = data.offsetTop

      $spy.affix(data)
    })
  })

It appears it is using window object instead of document. Thoughts?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.