रेल 4: $ का उपयोग कैसे करें (दस्तावेज़)। पहले से ही () टर्बो-लिंक के साथ


422

मैं जेएस फाइलों को "रेल मार्ग" को व्यवस्थित करने की कोशिश करते हुए अपनी रेल 4 ऐप में एक मुद्दे पर भाग गया। वे पहले अलग-अलग विचारों में बिखरे हुए थे। मैंने उन्हें अलग-अलग फाइलों में व्यवस्थित किया और उन्हें परिसंपत्ति पाइपलाइन के साथ संकलित किया। हालाँकि, मैंने अभी सीखा कि jQuery की "रेडी" घटना टर्बो-लिंकिंग चालू होने के बाद के क्लिक पर आग नहीं लगाती है। पहली बार जब आप एक पेज लोड करते हैं तो यह काम करता है। लेकिन जब आप एक लिंक पर क्लिक करते हैं, तो अंदर कुछ भी ready( function($) {निष्पादित नहीं होगा (क्योंकि पृष्ठ वास्तव में फिर से लोड नहीं होता है)। अच्छी व्याख्या: यहाँ

तो मेरा सवाल है: यह सुनिश्चित करने का सही तरीका क्या है कि टर्बो-लिंक चालू रहते हुए jQuery इवेंट ठीक से काम करें? क्या आप स्क्रिप्ट्स को रेल-विशिष्ट श्रोता में लपेटते हैं? या शायद पटरियों में कुछ जादू है जो इसे अनावश्यक बनाता है? डॉक्स इस बात पर थोड़ा अस्पष्ट हैं कि यह कैसे काम करना चाहिए, विशेष रूप से कई फाइलों को लोड करने के संबंध में प्रकट (एस) जैसे कि एप्लिकेशन। जेएस।

जवाबों:


554

यहाँ मैं क्या कर रहा हूँ ... 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 (टर्बोलिंक 5) page:loadबन जाता है turbolinks:loadऔर प्रारंभिक भार पर भी निकाल दिया जाएगा। तो हम बस निम्नलिखित कर सकते हैं:

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

  ...your javascript goes here...

});

3
क्या वह कॉफी लिपि है? मैंने इसे अभी तक नहीं सीखा है। क्या आपके उदाहरण के बराबर एक js या jQuery है?
एमर्सोथिसिस

6
मुझे लगता है कि मुझे मिल गया है: var ready = function() { ... } $(document).ready(ready) $(document).on('page:load', ready)क्या दोनों के लिए कोई चिंता है .readyऔर 'page:load'ट्रिगर हो रहा है?
एमेरोथिसिस


16
मैं पुष्टि कर सकता हूं कि तैयार फ़ंक्शन को दो बार कॉल नहीं किया जाता है। यदि यह एक कठिन ताज़ा है, केवलready घटना निकाल दिया जाता है। यदि यह एक turbolinks लोड है, केवलpage:load घटना निकाल दिया जाता है। दोनों के लिए readyऔर page:loadएक ही पृष्ठ पर निकाल दिया जाना असंभव है ।
क्रिश्चियन

7
FYI करें आप इसे कई आयोजनों के लिए भी लागू कर सकते हैं page:loadऔर readyपहले argumet के लिए एक अलग-अलग स्ट्रिंग शामिल कर सकते हैं। $(document).on('page:load ready', ready);दूसरा तर्क केवल एक फ़ंक्शन है, जिसका नाम readyइस उत्तर के उदाहरण के बाद दिया जाता है।
एहनबिजद

235

मैंने अभी इस समस्या को हल करने के लिए एक और विकल्प सीखा है। यदि आप मणि को लोड करते हैं तोjquery-turbolinks यह रेल टर्बोलिंक्स की घटनाओं को घटनाओं से बांध देगा document.readyताकि आप अपने jQuery को सामान्य तरीके से लिख सकें। आप js मेनिफ़ेस्ट फ़ाइल (डिफ़ॉल्ट रूप से ) के jquery.turbolinksठीक बाद जोड़ते हैं ।jqueryapplication.js


2
बहुत अच्छे धन्यवाद! वास्तव में मुझे क्या चाहिए। रेल रास्ता। कन्वेंशन।
जेरेमी बेकर

6
प्रलेखन के लिए रिकॉर्डिंग , आपको //= require jquery.turbolinksप्रकट (उदाहरण के लिए application.js) में जोड़ना चाहिए ।
एपोक्रीफलाउथोर

1
@wildmonkey दो उत्तर परस्पर अनन्य हैं। 0.o
एहनबेकद

1
जब आप इस मणि को जोड़ते हैं तो आपको अपने रेल सर्वर को फिर से चालू करना होगा
टोबी 1 केनोबी

21
कृपया ध्यान दें कि रेल 4 अब टर्बोलिंक्स 5 के लिए डिफ़ॉल्ट है, जो बदले में, jquery.turbolinks द्वारा समर्थित नहीं है! देखें github.com/kossnocorp/jquery.turbolinks/issues/56
सेबस्टियन

201

हाल ही में मैंने इससे निपटने के तरीके को सबसे साफ और आसान पाया:

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

या

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

संपादित करें
यदि आपने ईवेंट्स को बाध्य किया है document, तो सुनिश्चित करें कि आप उन्हें readyफ़ंक्शन के बाहर संलग्न करते हैं, अन्यथा उन्हें हर page:loadईवेंट पर रिबाउंड मिलेगा (समान फ़ंक्शन को कई बार चलाने के लिए)। उदाहरण के लिए, यदि आपके पास इस तरह की कोई कॉल है:

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

उन्हें readyइस तरह से कार्य से बाहर निकालें :

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

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

घटना के लिए बाध्य प्रतिनिधि को घटना पर बाध्य होने की documentआवश्यकता नहीं है ready


9
यह एक अलग ready()फ़ंक्शन बनाने के स्वीकृत उत्तर की तुलना में बहुत सरल है । readyफ़ंक्शन के बाहर प्रत्यायोजित घटनाओं को बाध्य करने के स्पष्टीकरण के लिए बोनस उत्तोलन ।
क्रिश्चियन

1
इस विधि के नुकसान पर यह है कि $(document).on( "ready", handler ), deprecated as of jQuery 1.8. jquery / तैयार
mfazekas

@Dezi @mfazekas यदि आप jQuery के पुराने संस्करणों का उपयोग कर रहे हैं, और jquery-turbolinks मणि के बिना यह समाधान काम करेगा? या readyमणि का उपयोग करके भाग को अमान्य बना दिया गया है?
एहनबिजद

इसे करने का सबसे सरल और आसान तरीका। यह कई फाइलों में वितरित जेएस कोड का समर्थन करता है और मुझे इस बात से परेशान नहीं होना है कि उन्हें किस क्रम में शामिल किया गया है। चर असाइनमेंट की तुलना में बहुत अधिक क्लीनर।
एवगेनिया मनोलोवा 10

3
आपको संभवतः "पेज: लोड" के बजाय "पृष्ठ: परिवर्तन" का उपयोग करना चाहिए, क्योंकि पूर्व को निकाल दिया जाता है चाहे पृष्ठ सर्वर से लोड किया गया हो या क्लाइंट-साइड कैश से
नाथन लॉन्ग

91

यह रेलिंग 4 डॉक्यूमेंटेशन में मिला है , जो डेमोज़्लुक के समाधान के समान है लेकिन थोड़ा छोटा है:

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

या

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

यदि आपके पास बाहरी स्क्रिप्ट हैं जो कॉल करते हैं $(document).ready()या यदि आप अपने सभी मौजूदा जावास्क्रिप्ट को फिर से लिखने से परेशान नहीं हो सकते हैं, तो यह रत्न आपको $(document).ready()TurboLinks के साथ उपयोग करने की अनुमति देता है : https://github.com/kossnocorp/jquery.turbolinks


79

नई रेल गाइड के अनुसार , निम्नलिखित करने का सही तरीका है:

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

या, कॉफ़्सस्क्रिप्ट में:

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

घटना को न सुनें $(document).readyऔर केवल एक घटना को निकाल दिया जाएगा। कोई आश्चर्य नहीं, jquery.turbolinks का उपयोग करने की कोई आवश्यकता नहीं है मणि ।

यह रेल के साथ काम करता है 4.2 और इसके बाद के संस्करण, न केवल 5 पटरियों।


अच्छा यह मेरे लिए काम किया। यहाँ हल करने की कोशिश की: stackoverflow.com/questions/17881384/… लेकिन किसी कारण से काम नहीं किया। अब मैं टर्बोलिंक पर लोड करता हूं: इसके बजाय लोड करता हूं
क्रिंकर

1
क्या कोई भी इस बात की पुष्टि कर सकता है कि "turbolinks:load"इवेंट रेल 4.2 में काम करता है? turbolinks:घटना उपसर्ग में पेश किया गया था नई Turbolinks और रेल में 4.2 IIRC जो Turbolinks का उपयोग करता है नहीं किया जाता है क्लासिक"page:change"अगर "turbolinks:load"आपके प्री-रेल 5 ऐप पर काम नहीं हो रहा है तो कोशिश करने पर विचार करें । गाइड
एलियट साइक्स

1
@EliotSykes गाइड को अपडेट नहीं किया गया है। रेलिंग्स 4.2 अब टर्बोलिंक्स-क्लासिक के बजाय github.com/turbolinks/turbolinks का उपयोग करता है । और किसी भी मामले में, यह इस बात पर निर्भर करता है कि आपने अपने जेमफाइल में क्या निर्दिष्ट किया है। आशा है कि आप जल्द ही इसकी पुष्टि करेंगे :)
vedant

3
धन्यवाद @ vedant1811 लेखन के समय, मैं पुष्टि कर रहा हूं कि एक नया रेल 4.2.7 ऐप टर्बोलिंक 5 (टर्बोलिंक्स-क्लासिक नहीं) का उपयोग करता है। इसे पढ़ने वाले डेवलपर्स - उपयोग किए गए टर्बोलिंक्स संस्करण के लिए अपने Gemfile.lock की जांच करें। यदि यह कम है तो 5.0 तो page:changeटर्बोलिंक्स का उपयोग या उन्नयन करें। यह भी पाया गया कि यह कुछ के लिए प्रासंगिक हो सकता है, जहाँ टर्बोलिंक पुरानी घटनाओं के नाम में घटनाओं का अनुवाद करता है: github.com/turbolinks/turbolinks/blob/v5.0.0/src/turbolinks/…
Eliot Sykes

1
क्या alert "page has loaded!"वास्तव में कॉलबैक फ़ंक्शन द्वारा चलाया जाने की आवश्यकता है?
mbigras

10

नोट: एक साफ, अंतर्निहित समाधान के लिए @ एसडीपी का जवाब देखें

मैंने इसे इस प्रकार तय किया:

सुनिश्चित करें कि आप एप्लिकेशन को शामिल करते हैं। अन्य एप्लिकेशन निर्भर जेएस फ़ाइलों को शामिल करने से पहले निम्न क्रम में बदलाव करके शामिल करें:

// 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');
});

2
यह सबसे साफ लगता है क्योंकि आपको इसे केवल एक जगह जोड़ना है, न कि हर कॉफ़ीस्क्रिप्ट फ़ाइल। अच्छा काम!
पाइरसपेड

@ Sled तो क्या यह SD और रत्न और इस कोड का उपयोग करने की विधि का उपयोग करने के लिए कह रहा है? या यह एक उत्तर है जो मणि का उपयोग नहीं करता है?
अहानिबेकद

इस उत्तर को भूल जाएं और एसडीपी के समाधान का उपयोग करें।
स्लेज

@sled क्या केवल एक स्थान पर कॉल डालने की धारणा के साथ एसडीपी के समाधान को संयोजित करना संभव है?
एहनबिजद

1
@gwho: जैसा कि SDP के जवाब से पता चलता है, टर्बोलिंक्स readyघटना तक पहुंच जाता है, इसका मतलब है कि आप इनिशियल करने के "मानक" तरीके का उपयोग कर सकते हैं $(document).ready(function() { /* do your init here */});:। जब पूरा पृष्ठ लोड हो जाए (-> बिना टर्बोलिंक के) तो आपका इनिट कोड कहा जाना चाहिए और जब आप किसी पेज को टर्बोलिंक्स के माध्यम से लोड करते हैं तो आपके इनिट कोड को फिर से निष्पादित किया जाना चाहिए। आप केवल एक turbolink इस्तेमाल किया गया है कुछ कोड निष्पादित करने के लिए करना चाहते हैं:$(document).on('page:load', function() { /* init only for turbolinks */});
स्लेज

8

उपरोक्त में से कोई भी मेरे लिए काम नहीं करता है, मैंने इसे jQuery के $ (दस्तावेज़) का उपयोग नहीं करके हल किया है। पहले से ही, लेकिन इसके बजाय addEventLiveener का उपयोग करें।

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

7
$(document).on 'ready turbolinks:load', ->
  console.log '(document).turbolinks:load'

यह एकमात्र समाधान है जो मेरे और प्रत्येक ब्राउज़र पर, टर्बोलिंक्स> = 5 के लिए काम करता है और जो पहले पृष्ठ लोड दोनों पर ट्रिगर करता है और जब आप किसी भी लिंक पर क्लिक करते हैं (टर्बोलिंक्स के साथ)। ऐसा इसलिए है क्योंकि जब क्रोम turbolinks:loadपहले पृष्ठ लोड पर ट्रिगर करता है, तो सफारी नहीं करता है और इसे ठीक करने के लिए हैक करने का तरीका (ट्रिगर turbolinks:loadपर application.js) जाहिर तौर पर क्रोम को तोड़ता है (जो इसके साथ दो बार फायर करता है)। यह सही जवाब है। निश्चित रूप से 2 घटनाओं के साथ readyऔर turbolinks:load
लुकासरूडा


3

या तो उपयोग करें

$(document).on "page:load", attachRatingHandler

या उसी प्रभाव को प्राप्त करने के लिए jQuery के .on फ़ंक्शन का उपयोग करें

$(document).on 'click', 'span.star', attachRatingHandler

अधिक जानकारी के लिए यहां देखें: http://srbiv.github.io/2013/04/06/rails-4-my-first-run-in-with-turbolinks.html


2

"तैयार" फ़ंक्शन को बचाने के लिए एक चर का उपयोग करने और इसे घटनाओं से बांधने के बजाय, आप readyजब भी page:loadट्रिगर कर सकते हैं तो घटना को ट्रिगर करना चाहते हैं ।

$(document).on('page:load', function() {
  $(document).trigger('ready');
});

2

यहां मैंने यह सुनिश्चित करने के लिए कि चीजों को दो बार निष्पादित नहीं किया है:

$(document).on("page:change", function() {
     // ... init things, just do not bind events ...
     $(document).off("page:change");
});

मैं का उपयोग कर पाते हैं jquery-turbolinksमणि या संयोजन $(document).readyऔर $(document).on("page:load")या का उपयोग करते हुए $(document).on("page:change")अपने आप में अप्रत्याशित रूप से बर्ताव करता है - खासकर यदि आप विकास में कर रहे हैं।


क्या आप यह समझाते हैं कि अप्रत्याशित रूप से व्यवहार करने का क्या मतलब है?
सूर्यनिरजेंजा

अगर मुझे $(document).offउस गुमनाम "पेज: चेंज" फंक्शन में बिट के बिना सिंपल अलर्ट रहता है, तो ऊपर दिया गया फंक्शन स्पष्ट रूप से उस पेज पर आने पर अलर्ट करेगा। लेकिन कम से कम विकास में चल रहे WEBrick, जब मैं किसी अन्य पृष्ठ के लिंक पर क्लिक करता हूं तो यह भी सतर्क हो जाएगा। इससे भी बदतर घटना, यह दो बार अलर्ट करता है जब मैं मूल पृष्ठ पर वापस लिंक पर क्लिक करता हूं।
ग्रे केम्मी

2

मुझे निम्नलिखित लेख मिला जिसने मेरे लिए बहुत काम किया और निम्नलिखित के उपयोग का विवरण दिया:

var load_this_javascript = function() { 
  // do some things 
}
$(document).ready(load_this_javascript)
$(window).bind('page:change', load_this_javascript)

2

मुझे लगा कि मैं इसे यहाँ Turbolinks 5 में अपग्रेड करने वालों के लिए छोड़ दूँगा : अपने कोड को ठीक करने का सबसे आसान तरीका है:

var ready;
ready = function() {
  // Your JS here
}
$(document).ready(ready);
$(document).on('page:load', ready)

सेवा:

var ready;
ready = function() {
  // Your JS here
}
$(document).on('turbolinks:load', ready);

संदर्भ: https://github.com/turbolinks/turbolinks/issues/9#issuecomment-184717346


2
$(document).ready(ready)  

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

2
हालांकि यह कोड स्निपेट प्रश्न को हल कर सकता है, जिसमें स्पष्टीकरण सहित वास्तव में आपकी पोस्ट की गुणवत्ता में सुधार करने में मदद करता है। याद रखें कि आप भविष्य में पाठकों के लिए प्रश्न का उत्तर दे रहे हैं, और उन लोगों को आपके कोड सुझाव के कारणों का पता नहीं चल सकता है।
andreas

4
दरअसल, यह जवाब गलत है। turbolinks:loadप्रारंभिक पृष्ठ लोड के लिए और साथ ही निम्न लिंक के बाद घटना की आग। यदि आप किसी ईवेंट को मानक readyईवेंट और ईवेंट दोनों से जोड़ते हैं turbolinks:load, तो जब आप पहली बार किसी पृष्ठ पर जाते हैं, तो यह दो बार फायर करेगा।
अलेक्जेंडरबर्ड

यह उत्तर गलत है। जैसा कि @alexanderbird ने कहा, यह readyबाद के पेज लोड पर दो बार आग लगाने का कारण बनता है। कृपया इसे बदलें या निकालें।
चेस्टर

@alexanderbird आपकी टिप्पणी ने मेरे लिए एक समस्या को हल कर दिया
अनवर

1

इतने सारे समाधान का परीक्षण आखिरकार इस पर आया। यह आपके कई कोड निश्चित रूप से दो बार नहीं कहा जाता है।

      var has_loaded=false;
      var ready = function() {
        if(!has_loaded){
          has_loaded=true;
           
          // YOURJS here
        }
      }

      $(document).ready(ready);
      $(document).bind('page:change', ready);


1

मैं आमतौर पर अपनी रेल 4 परियोजनाओं के लिए निम्नलिखित कार्य करता हूं:

में application.js

function onInit(callback){
    $(document).ready(callback);
    $(document).on('page:load', callback);
}

फिर .js फ़ाइलों के बाकी में, $(function (){})मैं कॉल का उपयोग करने के बजायonInit(function(){})


0

सबसे पहले, jquery-turbolinksमणि स्थापित करें । और फिर, अपने शामिल जावास्क्रिप्ट फ़ाइलों को अपने शरीर के अंत application.html.erbसे इसके स्थानांतरित करने के लिए मत भूलना <head>

जैसा कि यहां बताया गया है , यदि आपने स्पीड ऑप्टिमाइज़ेशन कारणों से एप्लिकेशन जावास्क्रिप्ट लिंक को पाद लेख में रखा है, तो आपको इसे टैग में स्थानांतरित करना होगा ताकि यह टैग में सामग्री से पहले लोड हो जाए। इस समाधान ने मेरे लिए काम किया।


0

मैंने पाया मेरी कार्यों दोगुनी जब के लिए एक समारोह का उपयोग कर readyऔर turbolinks:loadइसलिए मैं प्रयोग किया जाता है,

var ready = function() {
  // you code goes here
}

if (Turbolinks.supported == false) {
  $(document).on('ready', ready);
};
if (Turbolinks.supported == true) {
  $(document).on('turbolinks:load', ready);
};

अगर टर्बोलिंक्स का समर्थन किया जाता है तो इस तरह से आपके कार्य दोगुने नहीं होते हैं!

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.