[javascript] Rails 4 : 터보 링크와 함께 $ (document) .ready ()를 사용하는 방법

JS 파일을 “레일 방식”으로 구성하려고 할 때 Rails 4 앱에서 문제가 발생했습니다. 그들은 이전에 다른 견해에 흩어져있었습니다. 파일을 별도의 파일로 구성하고 자산 파이프 라인으로 컴파일했습니다. 그러나 터보 링크가 켜져있을 때 jQuery의 “준비”이벤트가 후속 클릭에서 발생하지 않는다는 것을 알게되었습니다. 페이지를 처음로드하면 작동합니다. 그러나 링크를 클릭 ready( function($) {하면 페이지가 실제로 다시로드되지 않기 때문에 내부의 어떤 것도 실행되지 않습니다. 좋은 설명 : here .

그래서 내 질문은 : 터보 링크가 켜져있는 동안 jQuery 이벤트가 올바르게 작동하도록하는 올바른 방법은 무엇입니까? Rails 전용 리스너에서 스크립트를 래핑합니까? 아니면 레일에 불필요하게 만드는 마법이 있습니까? 문서는 특히 application.js와 같은 매니페스트를 통해 여러 파일을로드하는 것과 관련하여 이것이 어떻게 작동하는지 조금 모호합니다.



답변

여기 내가하는 일이 있습니다 : CoffeeScript :

ready = ->

  ...your coffeescript goes here...

$(document).ready(ready)
$(document).on('page:load', ready)

마지막 줄은 터보 링크가 트리거 할 페이지로드를 청취합니다.

편집 … 자바 스크립트 버전 추가 (요청 당) :

var ready;
ready = function() {

  ...your javascript goes here...

};

$(document).ready(ready);
$(document).on('page:load', ready);

편집 2 … 레일 5 (Turbolinks 5)의 경우는 page:load되고 turbolinks:load, 심지어 초기로드에 발사 될 것이다. 따라서 다음을 수행 할 수 있습니다.

$(document).on('turbolinks:load', function() {

  ...your javascript goes here...

});


답변

나는이 문제를 해결하기위한 또 다른 옵션을 배웠다. gem 을로드 하면jquery-turbolinks Rails Turbolinks 이벤트를 이벤트에 바인딩 document.ready하여 일반적인 방식으로 jQuery를 작성할 수 있습니다. js manifest 파일 jquery.turbolinks바로 뒤에 추가 jquery하면됩니다 (기본 🙂 application.js.


답변

최근에 가장 깨끗하고 이해하기 쉬운 방법을 찾았습니다.

$(document).on 'ready page:load', ->
  # Actions to do

또는

$(document).on('ready page:load', function () {
  // Actions to do
});

편집에 바인딩 된 이벤트를 위임 한
경우 함수 외부에 첨부해야 합니다. 그렇지 않으면 동일한 함수가 여러 번 실행되므로 모든 이벤트에서 리바운드됩니다 . 예를 들어 다음과 같은 호출이있는 경우 :documentreadypage:load

$(document).on 'ready page:load', ->
  ...
  $(document).on 'click', '.button', ->
    ...
  ...

다음 ready과 같이 기능에서 꺼내십시오 .

$(document).on 'ready page:load', ->
  ...
  ...

$(document).on 'click', '.button', ->
  ...

에 바인딩 된 위임 된 이벤트는 이벤트에 바인딩 document될 필요가 없습니다 ready.


답변

이 발견 레일 4 문서 DemoZluk의 솔루션과 유사하지만 약간 짧은을 :

$(document).on 'page:change', ->
  # Actions to do

또는

$(document).on('page:change', function () {
  // Actions to do
});

호출하는 외부 스크립트가 $(document).ready()있거나 기존 JavaScript를 모두 다시 작성할 필요가없는 경우이 gem을 사용하면 $(document).ready()TurboLinks 를 계속 사용할 수 있습니다 . https://github.com/kossnocorp/jquery.turbolinks


답변

새로운 레일 가이드 에 따라 올바른 방법은 다음을 수행하는 것입니다.

$(document).on('turbolinks:load', function() {
   console.log('(document).turbolinks:load')
});

또는 커피 스크립트에서 :

$(document).on "turbolinks:load", ->
alert "page has loaded!"

이벤트를 듣지 마십시오 $(document).ready. 하나의 이벤트 만 시작됩니다. 당연히 jquery.turbolinks gem 을 사용할 필요가 없습니다 .

이것은 레일 5 이상이 아니라 레일 4.2 이상에서 작동합니다.


답변

참고 : 깨끗하고 내장 된 솔루션은 @SDP의 답변을 참조하십시오

다음과 같이 수정했습니다.

다음과 같이 포함 순서를 변경하여 다른 앱 종속 js 파일이 포함되기 전에 application.js를 포함시켜야합니다.

// in application.js - make sure `require_self` comes before `require_tree .`
//= require_self
//= require_tree .

바인딩을 처리하는 전역 함수를 정의하십시오. application.js

// application.js
window.onLoad = function(callback) {
  // binds ready event and turbolink page:load event
  $(document).ready(callback);
  $(document).on('page:load',callback);
};

이제 다음과 같은 것을 묶을 수 있습니다.

// in coffee script:
onLoad ->
  $('a.clickable').click =>
    alert('link clicked!');

// equivalent in javascript:
onLoad(function() {
  $('a.clickable').click(function() {
    alert('link clicked');
});


답변

위의 어느 것도 나를 위해 작동하지 않습니다 .jQuery의 $ (document) .ready를 사용하지 않고이 문제를 해결했지만 대신 addEventListener를 사용하십시오.

document.addEventListener("turbolinks:load", function() {
  // do something
});