I want to run this javascript on my homepage when it loads:
$(".mm-page").css({"position":"inherit"});
I added this at the bottom of my home.html.erb:
<% content_for(:after_js) do %>
<script type="text/javascript">
console.log("before");
$(".mm-page").css({"position":"inherit"});
console.log("after");
</script>
<% end %>
Both console.log appear in the console, but the jquery has no effect. If I manually run the jquery line in the console, it works as expected.
How should I proceed to fix this ?
Since you want to make it work on page when it load you should wrap it inside ready handler.The ready() method specifies what happens when a ready event occurs.
Two syntaxes can be used:
$(document).ready(function(){
$(".mm-page").css({"position":"inherit"});
});
OR
$(function() {
$(".mm-page").css({"position":"inherit"});
});
Also be sure that the element .mm-page exists in the moment you're using it with the jQuery selector.
To ensure that all of the DOM elements it operates on exist, put the script tag at the very bottom of the HTML, just prior to the closing </body> tag. All of the elements defined by the HTML above it will then be available for use. This also ensures that the browser can show the user the page prior to downloading any external script files you reference. E.g.:
<!doctype html>
<html>
<!-- ...your page here... -->
<script src="jquery.js"></script>
<script>
console.log("before");
$(".mm-page").css({"position":"inherit"});
console.log("after");
</script>
</body>
</html>
You'll need to translate that to whatever rendering engine you're using, but you get the idea. The end result going to the browser should look like that.
Alternately, you can use jQuery's ready callback, but with the script tags in the correct location, it's unnecessary.
Side note: The default type is JavaScript, there's no need to specify it on the script tag.
console.log appear in the console
Because your DOM has finished loading and it is now ready to use.
That's why you are getting jQuery effect.
In your current script,it is not waiting to finish DOM loading and directly operating on it which is not available as it is not finished loading.
Eiher write script it in
$( document ).ready(function() {
// Handler for .ready() called.
});
OR :
$(function() {
// Handler for .ready() called.
});
Related
On https://bm-translations.de/dolmetscher-franzoesisch-deutsch.php you can see the Header doesnt work like it does here: https://bm-translations.de
I guess out of some reason JS isnt working. But the strange thing is on reloading the page (strg + F5) its working. Whats wrong here?
I am loading Jquery first and in footer my own JS.
This is most likely a race condition. You're probably running your javascript before the DOM has had a chance to load. The reason it works on the second reload is that the browser is using the cached version of the scripts.
There are a few ways you can deal with this:
Make sure you script tags don't have an async attribute. This tells them they're allowed to load in any order they'd like so your script may load before jQuery has had a chance to load.
Make sure your scripts are in the right order. The simplest is to move your scripts into the bottom of the body so that the browser loads it last. Make sure your scripts go after any dependent scripts, such as jQuery.
<script src="jquery.js"></script>
<script src="myscript.js"></script>
</body>
The other option is to use a "ready" event. Since you're using JQuery, you already have access to this by simply wrapping your function in a jQuery object with a callback function.
console.log('this will run before the DOM is loaded');
// wait for DOM to load inside jquery callback
$(function() {
console.log('this will run after the DOM has loaded');
});
console.log('this will also run before the DOM is loaded');
The output of the above code would read:
'this will run before the DOM is loaded'
'this will also run before the DOM is loaded'
'this will also run before the DOM is loaded'
because you have added async attribute to jquery script tag.
you can not use the async attribute here if some other script is depending on jquery.
in https://bm-translations.de/dolmetscher-franzoesisch-deutsch.php
<script async src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js">
</script>
<script async src="https://cdnjs.cloudflare.com/ajax/libs/jquery.lazyload/1.9.1/jquery.lazyload.min.js"></script>
while in https://bm-translations.de
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js">
</script>
<script async="" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.lazyload/1.9.1/jquery.lazyload.min.js"></script>
more about async attribute.
I'm using HTML templates (Jekyll) and occasionally want to include scripts in the content of the template. For example, my page template looks like this
<body>
{{ content }}
<script src="some_library.js"></script>
<script>
// general setup stuff
</script>
</body>
Where {{ content }} can sometimes include
<script>
// page-specific code relying on some_library.js and general page setup stuff
</script>
I could just move the template scripts into the head of template, but I've read many times how important it is to put <script> at the end of the document. Can I reliably ensure that the page-specific code runs last even though it appears first?
I'm using jQuery, but if I include jQuery in the template, then it won't be available in the content script. I tried adding a $(window).load function around the content script, but I get $ is not defined.
You could directly work with the window load event instead of $(window).load - no need for jQuery!
The simplest way:
window.onload= yourFunction;
A cleaner way would be to rely on the attachEvent/addEventListener methods:
window.addEventListener ?
window.addEventListener("load",yourFunction,false) :
window.attachEvent && window.attachEvent("onload",yourFunction);
(attachEvent is for older IE versions)
Use jQuery's .ready() function.
From the documentation:
While JavaScript provides the load event for executing code when a
page is rendered, this event does not get triggered until all assets
such as images have been completely received.
Also from the docs:
$(function() {
// Handler for .ready() called.
});
I have JQuery based tab navigation that only works if it is placed after the html for the menu. It works if it's placed at the end too, but breaks when I put the same script in $(document).ready ath the top.
I thought that this (placed at the top of the page):
<script type="text/javascript">
$(document).ready(function(){
mouseovertabsmenu.init("mytabsmenu", "mysubmenuarea", true);
});
</script>
would be the same as this:
<script type="text/javascript">
mouseovertabsmenu.init("mytabsmenu", "mysubmenuarea", true);
</script>
</html>
Which is placed at the bottom of the page and works. How would I be able to put the function at the top or even include it from a separate file?
I had this problem and I had used this in the head after the jquery include link:
$(document).ready(myfunction());
This failed due to objects not being loaded. I should have wrapped my call in a function:
$(document).ready(function () {
myfunction();
});
This worked as expected only after the document was properly loaded.
The reason it is recommended to place the script at the end of the page , is so that the HTML elements are loaded onto the page before you try to access them..
No matter where you place the code it is better to wrap in DOM ready event which makes sure the complete HTML document is properly loaded before you try to access the elements in the page..
Maybe in your case
<script type="text/javascript">
mouseovertabsmenu.init("mytabsmenu", "mysubmenuarea", true);
</script>
seems to be working when not encased in DOM ready is the function is not accessible as it's scope is being blocked by DOM ready
I'm trying out jQuery for the first time, and I'm not sure how to make it work properly. I've included the following code near my opening <head> tag:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js" type="text/javascript"></script>
Followed by the following jQuery code:
<script>
$('.darkmask > img').hover(function(){
$(this).parent().toggleClass('darkmask-hover');
})
</script>
Unfortunately, this code doesn't work when I try it in a browser, or in JSFiddle. However, when I set JSFiddle's framework to load jQuery itself, rather than loading jQuery through my own code, the animation works properly.
Am I loading jQuery wrong? If so, what's the right way?
PRoblem is, your code in JSFiddle is executed on the loading on the page. In your code instead, the execution happens when the HTML elements are not yet loaded because it's in the HEAD, so the selectors like .darkmask actually refer to... nothing.
The solution is to use:
$(document).ready(
function()
{
... your code here
}
To ensure that it is executed when the page is loaded and ready, all the HTML elements are there and therefore JQuery selectors can operate on something.
Are there any HTML elements when the code is executed?
Try:
$(function () { // this function executes when the page loads
alert(x);
// put your code here
});
Wrap your entire code in the following:
$(document).ready(function() {
//ALL CODE GOES HERE
});
Wrap your code in:
$(function() {
.... Your code here ...
});
It will mean your code is executed after the DOM tree is loaded.
You do need to wrap your jQuery code within the ready function, like this:
$(document).ready(function(){
// put your code here.
});
Also make sure your script tags have type="text/javascript" as an attribute otherwise it won't get run as javascript.
Because of performance purposes I put loading of jQuery scripts at the bottom of the page (just before the closing body tag).
My question is how to enable page specific scripts? I don't want to put everything inside $(document).ready method (again because of performance purposes).
Update: I'm using a template system so I put jQuery loading in the template. That way jQuery calls don't get recognized even if I put them at the end of a specific page because jQuery is not loaded at that point.
I'm not 100% sure what you're asking, but if it's what I think it is, the answer is that you can't have your cake and eat it too.
It seems that you've moved jQuery to the button of the page but have some elements of the page that you want to use JavaScript on, but don't want to wait for document.ready for all of the? Maybe something like the following?
<html>
<body>
<ul id="maybe-some-menu-that-needs-js-initialization-for-example">
...
</ul>
<script>
/* javascript goes here that uses jquery for the above menu (or whatever)
AND you don't want to wait for document.ready for this to happen */
</script>
...
<script src="including jquery here"></script>
<script src="including other scripts here"></script>
</body>
</html>
If that's the case, then refer to what I said from the get-go. You'll have to move jQuery (at least the library, not necessarily all your other JavaScript) back to the top of the page. Either that or don't us jQuery for the things you don't want to wait for document.ready for.
Edit: If you want to perform actions based on the page that you are, then there are two methods, each better and more preferable then the last.
Use location.pathname to determine what functionality you need.
Organize your JavaScript into separate, modular files by their functionality and include only those that are needed for the specific page.
The $(document).ready() will not be overridden when using it more than once, so you can load 2 script files that both adds functionality to be run when the document is loaded.
using $(document).ready, it doesn't matter where in the page it is, as it will only execute when the DOM has finished loading. The only code that should go inside $(document).ready is code that needs to be set up when the DOM has loaded, e.g. event handlers, any effects/animations that you want to run as soon as the DOM has finished loading, etc. Other functions do not need to be in $(document).ready, such as a function used in sorting an array, named functions called when events are raised, etc.
As has been pointed out, you can have more than one $(document).ready function on a page, as what you are doing is specifying a function (named or anonymous) to execute when the ready event (a jQuery event) is raised.
EDIT:
That article that you have linked to in the comments on this answer provides and example of what you are trying to achieve. As an example, you would have a JavaScript file with the following setup to declare a global variable
var myPageLibrary = {
homePage : {
init : function() {
$(document).ready(function() {
/* page specific functions that need to run,
for exmaple, binding event handlers, etc */
});
}
},
aboutPage : {
init : function() {
$(document).ready(function() {
/* page specific functions that need to run,
for exmaple, binding event handlers, etc */
});
}
}
}
/* you might have functions here that are bound to events.
Here is an example */
function showSubMenu(e) {
$(e.target).next('div').show();
}
function hideSubMenu(e) {
$(e.target).next('div').hide();
}
Then in your pages, you would have the following structure (this example uses the home page)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>This is my Home Page</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script src="path-to-myPageLibrary.js"></script>
<script type="text/javascript">
myPageLibrary.homePage.init();
</script>
</head>
<body>
<!-- Page content -->
</body>
</html>
with jQuery script file referenced first, followed by myPageLibrary script file, followed by the script block calling myPageLibrary.homePage.init();
If I understand correctly, you need to put some javascript code that calls jquery in the middle of your page. But your jquery include is at the bottom of the body. You can do this by calling the jquery at the window.load event. This event fires after all async scripts have loaded and executed. e.g.:
<body>
<script>
$("#myElem").val(); // fails, "$" not defined
window.addEventListener("load", function(evt) {
$("#myElem").val(); // ok, jquery is loaded
});
</script>
<span id="myElem>hi</span>
<script src="//cdn.jquery.com"></script>
</body>
This allows you to call jQuery plugin methods in the body and load jQuery plugin on to bottom of the page headjs
Just have a page-specific $(document).ready().
Have you tried "#section script"? It will automatic add the codes at the end of the page, thus you can have page specific jQuery scripts.
#section scripts {
<script>
jQuery(document).ready(function () {
//put your jQuery codes here
});
</script>
}
As I understand your issue:
jQuery is not available on the page before it loads.
You use templates and each has it's own js code to run when page loads
You want them to run with jQuery.
If I got you right, here is the solution:
In <head> define global task array:
...
<script>
const JQUERY_READY_TASKS = []
</script>
</head>
After you load jQuery and other scripts define:
...
<script>
jQuery(document).ready(() => {
// Execute all tasks added by templates
for (let n=0; n<JQUERY_READY_TASKS.length; n++)
JQUERY_READY_TASKS[n](jQuery)
}
});
</script>
</body>
Wrap initialization code of your templates in functions:
...
<script>
// Within template
JQUERY_READY_TASKS.push(($) => {
// Template init code
// You can use $ as jquery here
})
</script>
...