So I'm trying to use Scrollify, which is a jQuery plugin for scroll snapping. I have jQuery imported no problem, but no matter how I import the plugin itself, I get the error:
Uncaught TypeError: $.scrollify is not a function
I have the plugin script loading after jQuery itself loads, and the configuration code after both of those load, even to the point where I put the plugin's script tag and configuration code at the very end of the page before </body>.
I've tried hosting the plugin script locally, and I tried using a CDN. Both gave the same issue.
I've had these sort of issues with other scripts and they always were due to the loading order, but I'm stumped here. Any help?
So I am building a custom Theme in OctoberCMS, and I was hopping to use scrollify before running into the same error. After a lot of struggling, switching JQuery versions and moving functions around, I noticed my issue was related to using Laravel Mix/Webpack to import the scrollify code. I had it required at the top of my main.js file, but the code itself was loaded after.
My solution was using some October twig functions to load the code after JQuery manually.
// These get loaded first
<script src="{{ [
'assets/js/app.js', // My JQuery gets loaded here
'assets/js/vue.js' // Other JS for the website
]|theme }}"></script>
// Scripts in here injected into page by the {% scripts %} tag after, having the
// scrollify.js in the array above or outside the {% put scripts %} tag would always throw
// $.scrollify is not a function error
{% put scripts %}
<script src="{{ 'assets/js/scrollify.js'|theme }}"></script>
<script>
$(document).ready(function () {
$.scrollify({
section: ".example-section",
});
});
</script>
{% endput %}
{% scripts %}
The {% scripts %} tag inserts JavaScript file references to scripts
injected by the application.
https://octobercms.com/docs/markup/tag-scripts
As the above answers mentioned, Scrollify needs to be loaded after the page and Jquery loads, but if you are using Webpack or equivalent I would suggest checking the compiled scripts in your browser and making sure they are ordered correctly.
Try putting your script at the bottom of your code.
...
<script>
$(function(){
$.scrollify({
...
});
});
</script>
</body>
Try to use it this way
jQuery(document).ready(function($) {
$.scrollify({
...
});
});
The reason behind the error is, that the Scrollify Script should initialize after the document has finished loading. Thus, the solution is to move it to the end
Move these two lines at the end of the body tag, as shown below:
<body>
..
..
..
<script src="..\js\Scrollify\jquery.scrollify.js"></script>
<script>
$(document).ready(function() {
$.scrollify({
section : ".sectionalScrolling",
});
});
</script>
</body>
Make sure that the script is right before the closing body tag.
Related
My JavaScript code only runs when the code is both inside the HTML file and called externally via
<script type="text/javascript" src="{{ url_for('static', filename='index.js') }}"></script>
<script>
var scroller = document.querySelector("#scroller");
...
</script>
I am using Flask and Jinja, with a file structure of:
/app
/static
index.js
/templates
base.html
myfile.html
routes.py
__init__.py
...
The code inside index.js is the exact same code between the <script> tags inside the HTML.
In terms of jinja and using block tags, base.html:
<body>
{% block content %}
<!-- typical HTML stuff here -->
{% endblock %}
<!-- some Bootstrap tags -->
<script ... ></script>
{% block script %}{% endblock %}
</body>
myfile.html:
<body>
...
{% block script %}
<script type="text/javascript" src="{{ url_for('static', filename='index.js') }}"></script>
{% endblock %}
<script>
...
</script>
The code itself works, and it worked not too long ago without this issue; I don't know what I changed to cause this, nor can I even imagine what could cause this. If there is more code that is required, I can easily share it.
Is there something I not understanding?
To note: I have had a similar issue trying to including external JavaScript code inside my HTML; at one point it wouldn't work, then it did, now it behaves the way I have described.
To further note: I have another .html file with its own external .js file that works fine.
Mr.#JakeJackson, Script in externl file never requires the same content to be available inside your inline code.
May be you are trying to process some elements and your script got executed before those elements are mounted to the document object.
A lazy solution to that problem is moving the external file linking tag to the bottom your HTML.Body.
OR
You can use defer attribute to your script element https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script
OR
If you have some libraries like jQuery included in your page, You can use the document.ready implementations in that
OR
you can implement your own document.ready like below
function myReady() {
return new Promise(function(resolve) {
function checkState() {
if (document.readyState !== 'loading') {
resolve();
}
}
document.addEventListener('readystatechange', checkState);
checkState();
});
};
myReady().then(function() {
// Put your app custom code here
});
I've added the cookie consent code from here
It has
<script>
...
if(readCookie('cookie-notice-dismissed')=='true') {
{% include ga.js %}
{% include chatbutton.js %}
}
...
</script>
in the html. This is placed within _includes but I can't figure out how to include javascript like /js/foo.js, located in another directory. I believe this is bundled with bundler within the jekyll assets.
Up to now, I've added javascript on my layouts in the following way, but haven't used {% include %} for this yet and I don't know how to let the _includes/cookie_consent.html know แบhere to find it.
<script src="/js/foo.js"></script>
<script>
$(function(){
new Foo(".js-foo");
});
</script>
I can see two options to solve this
you create a file in _includes that contains the links to the extra JS you want.
For example:
# /_includes/bar.html
<script src="/js/foo.js"><\/script>
Inside _cookie_consent.html you can then add{% include bar.html %}
You add the link directly to your body.
if(readCookie('cookie-notice-dismissed')=='true') {
const js = '<script src="/js/foo.js"></script>'
document.body.appendChild(js)
}
I have this weird problem where console.log does not work inside symfony application. Logging works in other sites though, for example:
http://www.w3schools.com/js/tryit.asp?filename=tryjs_output_console
Everytime i refresh that page, the console displays correctly: 11
here is the last part of my code inside the twig template
{% block javascripts %}
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js">
$(document).ready(function () {
$('.dropdown-toggle').dropdown();
console.log(5 + 6);
});
</script>
{% endblock %}
The dropdown function works correctly, so javascript is working. However the console does not display anything.
You need to end your <script> tags that have an src attribute (like you did with jQuery). When writing JavaScript between tags, they need to be independant to that JavaScript specifically. See the documentation for more information.
Specifically from the docs:
If a script element has a src attribute specified, it should not have a script embedded inside its tags.
Here's your code updated with the fix:
<script src="//code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script>
$(document).ready(function () {
$('.dropdown-toggle').dropdown();
console.log(5 + 6);
});
</script>
As my website has only one page, and the index.html was getting really long and impossible to read. So I decided to put each section in a different HTML file and use jQuery to included it.
I used jQuery's include in the way as it has been mentioned here to include a external HTML file but apparently it doesn't work for my website. I really don't know what is the problem.
Here is the link of my workspace.
Here is what I am doing in index.html file to include other sections
<script src="./js/jquery-1.11.1.min"></script>
<script>
$(function() {
$("#includedContent").load("./page1.html");
});
</script>
<script>
$(function() {
$("#includedContent").load("./page2.html");
});
</script>
<script>
$(function() {
$("#includedContent").load("./page3.html");
});
</script>
<script>
$(function() {
$("#includedContent").load("./page4.html");
});
</script>
<script>
$(function() {
$("#includedContent").load("./page5.html");
});
</script>
<script>
$(function() {
$("#includedContent").load("./page6.html");
});
</script>
<script>
$(function() {
$("#includedContent").load("./page7.html");
});
</script>
I also used this method to make sure the file is accessible and everything was fine. So the problem is not the accessibility of the files
You are overwriting the contents of #includedContent seven times (see documentation of jQuery.load). With AJAX, there is no guarantee which request will complete first so you will end up with random page content inside the container.
The solution is to create containers for each page and load each page inside its dedicated container, something like this:
<div id="includedContent">
<div class="page1"></div>
<div class="page2"></div>
<div class="page3"></div>
</div>
$(document).ready(function() {
$("#includedContent .page1").load("page1.html");
$("#includedContent .page2").load("page2.html");
$("#includedContent .page3").load("page3.html");
});
NB: Having said all that, I do not understand how AJAX solves the problem of the page being too long/impossible to read.
There are several things that look odd to me:
all your load functions run at document ready, which is weird while having all the same target. load replaces (not adds) the content of the selected element with what is being loaded, you probably are trying to add all the html contents, but your current setup would actually just load page7.html into #includedContent
the paths look strange to me, i guess ./ may cause errors, try to leave out ./ everywhere.
rather than loading an entire html page, you might just want to load a piece of that file (i dont know how pageX.html looks), for example you would not want to load the <html> node entirely, rather the content only: .load('page1.html #content')
are you including jquery correctly? there is no .js in your inclusion
I have recently discovered the new trend of including all .js script at the end of the page.
From what i have read so far seems pretty ok and doable with an exception.
The way I am working is using a template like:
<html>
<head>
<!-- tags, css's -->
</head>
<body>
<!-- header -->
<div id="wrapper">
<?php
include('pages/'.$page.'.php');
?>
</div>
<!-- footer -->
<!-- include all .js -->
</body>
</html>
Now, if I want to use this example on my page http://www.bootply.com/71401 , I would have to add the folowing code under my jquery inclusion.
$('.thumbnail').click(function(){
$('.modal-body').empty();
var title = $(this).parent('a').attr("title");
$('.modal-title').html(title);
$($(this).parents('div').html()).appendTo('.modal-body');
$('#myModal').modal({show:true});
});
But that would mean I either use that in every page - even if I do not have use for it, either generate it with php in the $page.'php' file and echoing it in the template file, after the js inclusion.
I am sure though, better methods exist and I don't want to start off by using a maybe compromised one.
Thanks!
Please avoid using inline scripts as they are not good maintainable and prevent the browser from caching them. Swap your inline scripts in external files.
Fore example you could put all your JavaScript in one file an check the presence of a specific element before initialize the whole code. E.g.:
$(document).ready(function(){
if($('.thumbnail').length) {
// your thumbnail code
}
});
A better way to execute "page specific" JavaScript is to work with a modular library like requirejs. You can modularize your scripts depending on their functionality (like thumbnails.js, gallery.js etc.) and then load the necessary script(s) depending e.g. on the existence of an element:
if($('.thumbnail').length) {
require(['ThumbnailScript'], function(ThumbnailScript){
ThumbnailScript.init();
});
}
The best way you can go is create a separate file for this code.
Let's name it app.js. Now you can include it under the jQuery inclusion.
<script type="text/javascript" src="app.js"></script>
This will prevent code repeat.
One more thing, pull all the code in $(document).ready(). Here is an example. So your app.js file will look like this:
$(document).ready(function(){
$('.thumbnail').click(function(){
$('.modal-body').empty();
var title = $(this).parent('a').attr("title");
$('.modal-title').html(title);
$($(this).parents('div').html()).appendTo('.modal-body');
$('#myModal').modal({show:true});
});
})