I building an app in Rails 4. I have the below JS plugins on my show page but they seem to work only when I manually reload the page.
I read that this might be due to turbolinks but since these plugins are in the body and not the head, it doesn't seem like a turbolinks issue.
I even tried pasting these in the head and the footer tags but these gave me the same issue. Sometimes, one of the plugins loads and the other doesn't.
The first plugin below are AddThis social buttons and the other is an image gallery.
Any suggestions?
Demo page http://mktdemo.herokuapp.com/listings/45
<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ashfaaq">
</script>
<script>
jQuery(document).ready(function($) {
$('#gallery-1').royalSlider({
fullscreen: {
enabled: true,
nativeFS: true
},
controlNavigation: 'none',
autoScaleSlider: true,
autoScaleSliderWidth: 960,
autoScaleSliderHeight: 850,
imageScaleMode: 'fit-if-smaller',
navigateByClick: true,
numImagesToPreload:2,
arrowsNav:true,
arrowsNavAutoHide: true,
/* arrowsNavHideOnTouch: true, */
keyboardNavEnabled: true,
fadeinLoadedSlide: true,
globalCaption: false,
globalCaptionInside: false,
loop: true,
thumbs: {
appendSpan: true,
firstMargin: true,
paddingBottom: 4
}
});
});
</script>
You can find the answer to your question here:
Rails 4 turbo-link prevents jQuery scripts from working
Rails 4 is using Turbolinks, which load the page javascript and css only once and then replaces only the body and title in the header. This is why jQuery(document).ready will only work if you reload the page.
In order to trigger your javascript, you have to use Turbolinks events like
page:change the page has been parsed and changed to the new version and on DOMContentLoaded
or
page:load is fired at the end of the loading process.
More details here: https://github.com/rails/turbolinks/#events
Here you can just replace your
jQuery(document).ready(function($) {
...
By
$(document).on('page:load', function($) {
...
Sounds like turbolinks is the cause of your problems.
You can either install this gem: Jquery Turbolinks
Or you could replace
jQuery(document).ready(function(
....
));
with
$(document).on('page:load', function(
....
));
Here is a nice copy/paste of why turbolinks causes some problems with jquery.
TurboLinks is a PJAX like library that asynchronously requests the content of the next page and inserts it into the current page’s body instead of requiring a full page reload. It speeds up page load times nicely. However, because the page is reloaded, the DOMContentLoaded event is triggered and your jQuery document.ready event wont be triggered.
Source
I had the same issue with my jQuery image gallery on Rails 5. It would not load unless the page was refreshed. After a year of (on and off) trying, here's the hack that worked for me:
Wrap your jQuery gallery code in a function:
var delayLoad = function(){
$('#gallery-1').royalSlider({
...
})
}
Then call it with setTimeout:
setTimeout(delayLoad, 250)
This solved the issue for me every time without having to refresh the page.
Related
my website has Turbolinks.
I need to inject a javascript TAG from Nielsen.
This is the code
<script>
!function(t,n){t[n]=t[n]||{nlsQ:function(e,o,c,r,s,i){return s=t.document,r=s.createElement("script"),r.async=1,r.src=("http:"===t.location.protocol?"http:":"https:")+"//cdn-gl.imrworldwide.com/conf/"+e+".js#name="+o+"&ns="+n,i=s.getElementsByTagName("script")[0],i.parentNode.insertBefore(r,i),t[n][o]=t[n][o]||{g:c||{},ggPM:function(e,c,r,s,i){(t[n][o].q=t[n][o].q||[]).push([e,c,r,s,i])}},t[n][o]}}}(window,"NOLBUNDLE");
var nSdkInstance = NOLBUNDLE.nlsQ("P38E2BEBD-E82F-4F94-9BA9-1A4EC618F5AF","nlsnInstance");
var nielsenMetadata = {
type: 'static',
assetid: "<%=hashed_url(url_for(only_path: true))%>",
section: 'D_BRW'
};
nSdkInstance.ggPM("staticstart", nielsenMetadata);
</script>
Basically the response from Nielsen is that tag is not implemented in the right way because when I change section of my website the instance is initialized again.
I think the issue are Turbolinks but I cannot disable them...
Any hint?
I recently used accordion jquery to help me expand/collapse content ( like a drop-down menu )..I used this script and placed it in the <body>
Script:
jQuery(document).ready(function($)
{
$("#accordions-727.accordions").accordion({
active: "",
event: "click",
collapsible: true,
heightStyle: "content",
animated: "swing",
})
})
The script is working fine but the page is not loading correctly..When I view or refresh the page, all the contents inside the drop-down menu becomes visible but once the page finishes loading everything becomes fine..Now how can I fix this?..Should I place the script in the <head>?
This is using jQueryUI accordion implicitly #Stew.
You have a wrong attribute in your accordion setup code, use the animate in place of animated.
Take a look in this API documentation: http://api.jqueryui.com/accordion
And it's the original component demonstration: http://jqueryui.com/accordion/
I suggest you to take a look in your jQuery files too, if they are OK and in the correct order (in <header> section).
Another point is to put your JavaScript in <header> section of your HTML and be sure you have no conflict or using older jQuery files versions than the component needs.
Hope it helps.
I have some javascript below which loads upon first page load, but then get lost by pjax.
Any way to solve this pls? I just have pjax running on the in application.html file so should i make it less aggressive or is there some js magic that will hold my js code.
$(document).ready(function() {
$("#note_label_tokens").tokenInput("/labels.json", {
crossDomain: false,
prePopulate: $("#note_label_tokens").data("pre"),
theme: "facebook"
});
});
Make the JS into a function, and then call it on document.ready and when the end.pjax event is fired.
I'm using jquerynewsticker to reveal 100,000 digits of the number π in a news ticker fashion.
If i have my Chrome inspector open, i can see that the page loads from top to bottom, but the after the number, as well all the JS behind it, is rendered black for a few seconds, and only then becomes coloured as per default. However, the script already starts running as you can see on the test page here: http://marckremers.com/pi/ticker/
It seems to run, but without rendering.
If i reduce the size of the number, it works.
So it's clearly an issue where the loading isnt complete.
How can I force the script to only play once everything has 100% loaded?
Looking at your website I see the you load the ticker plugin and you execute your own code:
jQuery(document).ready(function($) {
$(function () {
$('#js-news').ticker({
speed: 0.05,
fadeInSpeed: 0,
titleText: '',
controls: false,
});
});
});
There 2 issues in this code:
1) Unnecessary nesting. you execute your code on document ready and then you call again a document ready handler ($(function(){...});
Keep in mind that writing $(document).ready( function(){} ) or $(function(){}) serves exactly the same purpose. For this reason you can remove the second event listener (useless):
jQuery(document).ready(function($) {
$('#js-news').ticker({
speed: 0.05,
fadeInSpeed: 0,
titleText: '',
controls: false,
});
});
with document.ready registration your code will run after the DOM has been completely built.
2) Another issue I see is that your selector #js-news does not resolve! I see no element in the page with ID=js-news... am I missing something ?
You can put your code as above to wait for the dom to be fully loaded.
$(function() {
// Your code
});
If it's not enough, if you want to wait for everything to be loaded (images, css, ...), you can put your code as above :
$(function()
{
$(window).bind('load', function()
{
// Your code
});
});
I have a Fancybox (or more accurately) a number of fancy boxes on an asp.net page.
My Fancybox (jquery plugin) works fine until a postback occurs on the page then it refuses to work.
Any thoughts? Anyone experienced similar behaviour?
UPDATE : Some Code..
I have a databound repeater with a fancybox on each repeating item.
They are instanciated by (outside the repeater)
$(document).ready(function() {
$("a.watchvideo").fancybox({
'overlayShow': false,
'frameWidth' : 480,
'frameHeight' : 400
});
});
The anchor tag is repeated..
href="#watchvideo_<%#Eval("VideoId")%>"
As is a div with
id="watchvideo_<%#Eval("VideoId") %>
As is a script element that instanciates the flash movies
Yes the VideoIds are being output the the page.
UPDATE : It's not a problem with the flash..
It is not a problem with the flash as i've tried it without the flash, it wont even pop a window with a simple message in.
UPDATE : I wonder if it is the updatepanel.
Rebinding events in jQuery after Ajax update (updatepanel)
-- lee
The problem is in using $(document).ready() to bind the fancybox. This code is only executed once, when the page is originally loaded. If you want the fancybox functionality on every postback, synchronous or asynchronous, replace the $(document).ready() with pageLoad(sender, args). i.e.
function pageLoad(sender, args) {
$("a.watchvideo").fancybox({
'overlayShow': false,
'frameWidth' : 480,
'frameHeight' : 400
});
}
see this answer for more info
Could it be that the instantiating code is being inserted at a piece of code which is not run after a postback?
It was the Update panel as described
here.. Rebinding events in jQuery after Ajax update (updatepanel)
As suggested I simply replaced
$(document).ready(function() {
$("a.watchvideo").fancybox({
'overlayShow': false,
'frameWidth' : 480,
'frameHeight' : 400
});
});
with
function pageLoad(sender, args)
{
if(args.get_isPartialLoad())
{
$("a.watchvideo").fancybox({
'overlayShow': false,
'frameWidth' : 480,
'frameHeight' : 400
});
}
}
and it worked!
-- Lee
This might help someone else, but FancyBox appends it's code to the <body> element... which is all fine and well, but resides OUTSIDE the asp.net <form> element. My postback problems went away when I modified FancyBox to append its dom objects to the <form> element:
$('body form:first').append( ... );
I had a similar problem with a paged grid-view. The first page of the grid was launching the fancybox while the remaing did not.
I thought it could be an issue related to the UpdatePanel which refreshes only a portion of the screen.
I solved the issue replacing this:
<script>
$(document).ready(function () {
$("a.small").fancybox();
});
</script>
with this:
<script>
function pageLoad(sender, args) {
$("a.small").fancybox();
};
</script>