I have an interesting problem. I'm working on a wordpress/woocommerce child theme. In the header, I have javascript that helps create a loading overlay until everything on the webpage is loaded using document ready to add a class to the overlay element.
$(document).ready(function(){ document.getElementById("page-load").className = "loaded" });
It's not working because of a javascript/jQuery conflict i reckon. I need this script in the header for obvious reasons(loaded asap), but I don't have control over the other scripts in the theme that are mostly in the footer.
How can I prevent the error:
$ is not defined
If it's a matter of waiting for document load you can try:
document.addEventListener("DOMContentLoaded", function() {
document.getElementById("page-load").className = "loaded";
});
Related
I've used my script on Tampermonkey (Firefox) for 6 month.
At now I have this error, script work partially, not all time.
I don't know why.
I have tries various suggestions about jQuery, doesn't work
Top of my script:
(function() {
'use strict';
function RPP(){
RedeemRPProduct('fp_bonus_100');
}
var body = $('body'); //I think error is here..
var points = {};
At now script works some times. When it doesn't works appear in console this error:
ERROR: Execution of script 'script-name' failed! $ is not defined
What's happened?
Thanks
I think the cause is that the website administrators removed jQuery from their code. With modern JS, it's mostly obsolete for things like selectors. I recommend simply removing jQuery references from your script and use normal DOM API:
To access body:
document.body
To find an element using selector:
document.querySelector("div#my_div")
Alternatively you could include jQuery in your script using #require.
I see your problem is solved, but leaving this here for others with the same error...
I'm also using Firefox, and my Tampermonkey was 1 year old (I forgot that I disabled the addon's auto updating). It worked fine, I never had the problem you described. Till a couple of days ago when I updated to the new version, and my userscripts stopped loading 10% of the times (got the mentioned error message in console).
Newer Tampermonkey-s are much faster than older versions, loading the userscripts earlier, sometimes before the jQuery library script of the original site is loaded, even if you are using // #run-at document-end.
How I fixed: wrapped my whole userscript content into 1 function, which is called only when the jQuery script is 100% loaded, using a checker function.
Add the next line to the top of your script, right after the Header:
function runScript() {
Add the next lines to the bottom of your script (to the end):
};
var waitForJQuery = setInterval(function () {
if (typeof $ != 'undefined') {
$(runScript);
clearInterval(waitForJQuery);
}
}, 100);
You're referencing jQuery (via the $) before it has loaded into the page.
It is working sometimes as I'm guessing on some occasions jQuery manages to load before you make your call...but sometimes it doesn't and you see the error.
Try this:
<script src="...your jquery reference..."/> <!-- at the top of your page -->
<!-- at the bottom of the page -->
<script>
var body;
var points = {};
document.addEventListener("DOMContentLoaded", function() {
body = $(body); //it won't try and use jQuery until the doc is ready
//...other script stuff...
});
</script>
I have a widget with some custom js:
class ImagePreviewWidget(ClearableFileInput):
...
class Media:
css = {
'all': ('css/image-preview-widget.css',)
}
js = ('js/image-preview-widget.js', )
The custom js uses jQuery, which is loaded independently, so I need to wrap my module initialization in:
window.onload = function() {
cusomJsStart();
};
Which is not very clean (one problem is that I am maybe interfering with other window.onload calls). Is there a better way to load the widget javascript?
EDIT
Just to make it clear: the whole point of this question is that jQuery is not yet loaded when the script runs, and that the script loading order is outside my control.
Instead of setting window.onload you should use addEventListener:
window.addEventListener("load", customJsStart);
(If you need to support IE<9 then some fallback code is required - see the MDN link above).
Even nicer would be if you could tell Django to add a defer attribute to the scripts you pass in the Media class, but it doesn't support that yet.
There is nothing better than pure Javascript ! Alternatively you can use JQuery like this :
$(function(){
cusomJsStart();
});
But with this method your page will be heavier because of JQuery source file loading.
Or you can put your cusomJsStart() at the end of your HTML file, but it's not clean at all !
You did the right choice.
Hello guys I have one question...
I use JQM 1.4 ... and it sometimes happens that when i click a button an get reddirected (to a new HTML5 file)... on the new page the header and footer are without style... it doesn't happen always but I cant have a page like this...
For the footer and header I use external HTML files (header.html and footer.html) and i call them with
$('#pageprostoriheader').load('header.html').trigger("create");
$('#pageprostorifooter').load('footer.html').trigger("create");
As I said it doesn't happen very often but when it does is ugly ...
I have a multiPage template and i think maybe this is caused because the header and footer don't get loaded quick enough .... so its possible to make like a loader that waits till is everything ready till it shows the page ?
As of jQuery Mobile 1.4, .trigger("create") is deprecated and will be removed on 1.5. Moreover, to create header/footer you should have used .trigger("pagecreate"), however, it is also deprecated and will be removed.
The replacement of the aforementioned functions is .enhanceWthin() to be called on parent element. This issue has several solutuins
Enhance toolbars after successful .load(), using .toolbar().
$('#pageprostoriheader').load('header.html', function () {
$(this).toolbar();
});
$('#pageprostorifooter').load('footer.html', function () {
$(this).toolbar();
});
Enhance toolbars after successful .load(), using .enhanceWithin() on active page.
$('#pageprostoriheader').load('header.html', function () {
$.mobile.pageContainer.pagecontainer("getActivePage").enhanceWithin();
});
$('#pageprostorifooter').load('footer.html', function () {
$.mobile.pageContainer.pagecontainer("getActivePage").enhanceWithin();
});
If you're using the same toolbars on all pages, I recommend using External toolbars.
Add HTML markup of header and footer in <body> not inside page div, and then add the below code in head after jQuery Mobile.js.
$(function () {
$("[data-role=header], [data-role=footer]").toolbar();
});
Jquery Mobile has decided to treat anchor links as page requests of sort. However, this isn't good if you have a load of blog posts which have anchor links to the same page (ie href="#specs").
Is there a way to disable jquery mobile's anchor link usage on a specific page which I know I won't be using it on so I can use anchor links as they were intended, to drop down to a part of the page?
I only need a solution for anchor links on the same page (ie: href="#specs").
thanks
You could try adding a data-ajax="false" on the anchor tag.
Linking without Ajax
Links that point to other domains or that have rel="external",
data-ajax="false" or target attributes will not be loaded with Ajax.
Instead, these links will cause a full page refresh with no animated
transition. Both attributes (rel="external" and data-ajax="false")
have the same effect, but a different semantic meaning: rel="external"
should be used when linking to another site or domain, while
data-ajax="false" is useful for simply opting a page within your
domain from being loaded via Ajax. Because of security restrictions,
the framework always opts links to external domains out of the Ajax
behavior.
Reference - http://jquerymobile.com/demos/1.0.1/docs/pages/page-links.html
If you are like me, converting an existing site and you don't want to go through every page right now. You can add one line of code to your header and all of your header and all of your existing internal anchor links will get the data-ajax="false" tag added.
Of course, this assumes you are including your own javascript file up in the header already. If you are not you would have to touch every page anyway. But I have a single javascript file that is included in every page already so I added this line...
$("a").each(function () { if(this.href.indexOf("#")>=0) $(this).attr("data-ajax",false); });
This goes in your $(document).ready() block. If you don't have that block yet, here is the entire block.
$(document).ready(function() {
$("a").each(function () { if(this.href.indexOf("#")>=0) $(this).attr("data-ajax",false); });
});
Hope this helps. It is the same solution user700284 offers but in an automated way.
You can add the following code to the end of your page:
<script type="text/javascript">
$('a.native-anchor').bind('click', function(ev) {
var target = $( $(this).attr('href') ).get(0).offsetTop;
$.mobile.silentScroll(target);
return false;
});
</script>
And add the class "native-anchor" to your anchor links.
It is not a total sollution, because the back button of your browser will move you to the previous page and not to the position of the link, but it is better than the links not working at all.
I found this sollution here: jQuery Mobile Anchor Linking
$(document).bind("mobileinit", function () {
$.mobile.ajaxEnabled = false;
});
First you have to place this code into a custom.js file
$(document).bind('mobileinit', function () {
$.mobile.loader.prototype.options.disabled = true;
$.mobile.ajaxEnabled = false;
$.mobile.linkBindingEnabled = false;
$.mobile.loadingMessage = false;
});
Then add this file into your webpage before the jquery mobile js is loaded. becuase 'mobilinit' event is triggered immediately
Thank you
this solution worked for me
<script>
$(document).ready(function() {
$("a").each(function() {
if (this.href.indexOf("index.php") >= 0) $(this).attr("data-ajax", false);
});
});
</script>
I replaced # with index.php which is my document root.
But, it doesn't work for form button i.e input type="submit"
// On page load on mobiles only, look for the specific a tag you want to take control over,
// alternatively you can still target all 'a' tags
$('a[href*="#component"]').each(function () {
// then set data-ajax to false,
$(this).attr("data-ajax", false);
// at this point you can add the class to your target a tags.
// You can do it elsewhere but because for this example my
// 'a' tags are automatically generated so I just add the class here
$(this).addClass('in-pagelink');
// then target the class and bind to a click event
$('a.in-pagelink').bind('click', function (ev) {
// here I redirect the page with window.location.assign
// as opposed to window.location.href. I find that it works better
window.location.assign(this.href);
// then I close my navigation menu
closeAll();
});
});
I'm developing a mobile website using the jQuery Mobile library. I have a header, a footer and a content area on the main page, and any links are loaded into the content area using the following code:
$("a").click(function() {
var toLoad = $(this).attr('href');
// Loading image
$('#content-body').html('<table class="loader"><tr><td><img src="<?php echo SITE_ROOT; ?>/img/ico/loader.gif" /></td></tr></table>');
$('#content-body').load(toLoad);
This works fine, except that the jQuery Mobile styles don't apply to content included this way. For example, the home page includes buttons:
Inventory
But when I load that page asynchronously into the content div, the links do not appear as buttons. Is there any way to tell jQuery Mobile to apply the mobile styles every-time #content is reloaded?
You sure can. You want to use .trigger('create') to initialize any jQuery Mobile widget:
$("a").click(function() {
var toLoad = $(this).attr('href');
// Loading image
$('#content-body').html('<table class="loader"><tr><td><img src="<?php echo SITE_ROOT; ?>/img/ico/loader.gif" /></td></tr></table>');
$('#content-body').load(toLoad, function () {
$(this).trigger('create');//it's that easy :)
});
});
Note that you call .trigger('create') on the parent element of the widget you want to initialize. Also note that since you are loading content through an asynchronous function you will need to call .trigger('create') in the callback function for your .load() call so that the elements to initialize are actually present when you try to initialize them.
Also you can sometimes run into an issue where the widget has been initialized but then you changed it's HTML and want to refresh the widget instead. There are functions to do this such as: .listview('refresh'), .slider('refresh'), etc.
I just answered a question regarding widgets needing to be initialized or refreshed: how to refresh jquery mobile listviews
Also you will want to change that .click() to a .delegate() so the links that are loaded via AJAX will also have this event handler attached:
$('#content-body').delegate('a', 'click', function() {
var toLoad = this.href;//no need to use jQuery here since `this.href` will be available in all major browsers
// Loading image
$('#content-body').html('<table class="loader"><tr><td><img src="<?php echo SITE_ROOT; ?>/img/ico/loader.gif" /></td></tr></table>');
$('#content-body').load(toLoad, function () {
$(this).trigger('create');//it's that easy :)
});
});