jQuery ready - how to strip an existing ready handle? - javascript

I've been asked to perform maintenance on a third party site, I can edit the javascript but not the back end code. This site uses a plugin which sets various styles and events up in a jQuery.ready call. I want to stop it without causing errors. I can insert javascript before and after the plugin in the template but the markup inside the plugin comes from elsewhere. I have tried something like this:
<script>
var tmpReady = $.ready;
$.ready = function() {};
</script>
<pluginWhichICanNotChange>
$(document).ready( function(){ BAD STUFF } );
</pluginWhichICanNotChange>
<script>
$.ready = tmpReady;
</script>
But the BAD STUFF still fires. Anyone any idea how I can strip it!?

That's because the methods that work with selectors reside in the $.fn namespace. The following should work:
<script>
var realReady = $.fn.ready;
$.fn.ready = function() {};
</script>
<pluginWhichICanNotChange>
$(document).ready(function() { /* BAD STUFF */ });
</pluginWhichICanNotChange>
<script>
$.fn.ready = realReady;
</script>

Related

Avoid using window.onload but still grab a script and then run a function

I am running a function through a jupyter notebook. Due to some reasons the window.onload function does not seem to work.
For example (this is just an example, not the actual code I am working with - I know this is not best practice), lets say I have the following page:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.js"/>
<script>
window.onload = function() {
// use some jquery function here
}
</script>
Is there a way to convert this into something like this using vanilla javascript:
<script>
get("https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.js").then(
// use some jquery function here
)
</script>

Be sure that never have JQuery conflict

I need to create code which can be used as snipped for every site.
When I copy paste this code to any html in the world this should work:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script type="text/javascript"> my_jQuery = $.noConflict(true);</script>
<script type="text/jscript">
my_jQuery(document).ready(function () {
my_jQuery("#myDiv").html("Hello world");
});
</script>
<div id="myDiv">
</div>
Of Course in real world logic will be more complex but principle is same.
So this must work even if site already have JQuery, if have same version of JQuery,if have different version of JQuery, or even if does not have JQuery at all.
I want be sure that client does not use some old version of JQuery, so I want always use my JQuery.
What do you think, will this work or there is something that I have not consider?
I think that this question should be faced in an architectural way, knowing what libraries/frameworks are available is a design concern... Basically, you shouldn't need to check dependencies at runtime... if you write jQuery, you must be sure that jQuery exists!
By the way, there are some cases where you can't do it, for example, if you are writing a public/api (a snippet that runs in heterogeneous environments). In these cases, you can do:
mark jQuery as peer-dependencies
Check at runtime.
There is an example of runtime checking:
<script>
(function($) {
var jQueryUrl = 'https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js';
$ || (document.writeln('<script src="'+ jQueryUrl +'"></script>'));
})(window.jQuery);
</script>
In order to avoid conflicts, finally, you don't need to use jQuery.noConflict, you need to work with javascript scopes (closures)... basically, never try to access the global jQuery alias $ (never use global vars), simple pass it as function param:
(function($) { console.log('$', $); })(window.jQuery)
window.jQuery(document).ready(function($) { console.log('$', $); });
The first thing we need to do is check if jQuery is present on the website. jQuery is the global variable so it should be in window object if it is loaded. We can check it like this: if (window.jQuery) {}
If the jQuery not present we can dynamically load it adding script tag with desired jQuery version. So the snippet answering for checking if jQuery is loaded and loading if it's not would be like:
if (!window.jQuery) {
var jq = document.createElement('script');
jq.type = 'text/javascript';
jq.src = 'http://code.jquery.com/jquery-1.12.1.min.js';
document.getElementsByTagName('head')[0].appendChild(jq);
}
That would work for
So this must work even if site already have JQuery,
if have same version of JQuery,
if have different version of JQuery,
or even if does not have JQuery at all.
As you can see as per your code, that would work fine for all three situations but 4th one. For this case you have to have a check to find if window has jQuery object. That can be done with:
if(window.jQuery){
var my_jQuery = $.noConflict(true);
my_jQuery(document).ready(function () {
my_jQuery("#myDiv").html("Hello world");
});
}
Note:
<script type="text/jscript">
would not work in the browsers other than IE.

Backbone script executing before document fully loaded

I am building my first rails app with backbone and because of the asset pipeline the Javascript is getting called/executed even before the document fully loads. So, none of the event handlers are getting attached. If I place this Javascript after the HTML tags at the end of the document, then it seems to work fine. How can I have this code execute after the page is fully loaded? I can always use jQuery's document.ready(), but I was hoping backbone has an inbuilt process to deal with it.
<script type="text/javascript">
(function() {
"use strict";
var app;
app = {};
app.AppView = Backbone.View.extend({
el: "body",
initialize: function() {
this.playAudio();
},
events: {
"click .play-audio": "playAudio"
},
playAudio: function() {
alert($("span").data("audio"));
}
});
app.appView = new app.AppView();
}).call(this);
</script>
<div>
<p>Whatever!</p><span class="glyphicon glyphicon-volume-up play-audio" data-audio="http://my-audio-file"></span>
</div>
Assign your function as document.onload or window.onload property. Both does almost the same thing but mostly depends on browser.
<script> document.onload=(...your function goes here....) </script>
//OR
<script> window.onload=(...your function goes here....) </script>
The fastest way to execute your code is by using the DOMContentLoaded event listener:
Here's how:
<script>
document.addEventListener("DOMContentLoaded", function(event) {
//your code here
});
</script>
Other useful event listeners are:
window.onload = myfunction() ;
//or
document.onload = myfunction();
Good luck!
You can easily overwrite the default render method for this.
Simply like this: (excuse me my coffee-script)
render: () ->
super()
#customMethodToRunAfterThePageIsLoaded()
I use it for after-page-load calculations which are inserted into the html with jQuery.

Extract and execute scripts from AJAX response

My AJAX response returns something like this:
<div>
..
</div>
<script type="text/javascript">
..
</script>
<script type="text/javascript">
..
</script>
<div>
..
</div>
I want to execute scripts from script tag (should work cross-browserly) and to insert text (divs) to page after.
Your script tags don't need the type="text/javascript" attribute for cross-browser compatibility.
And your JavaScript will execute from the top down. So whatever script comes first will execute first. Add your text insertion last, something like this:
HTML:
<div id="myDiv"></div>
JavaScript:
document.getElementById("myDiv").innerHTML = "hello";
Extract scripts from ajax responses is generally bad practice (caching, security,...).
It's better to handle data (JSON) returned in the ajax response. Consider to use JQuery or another framework since they offer cross-browser functionality and DOM manipulation build-in.
See the following DOM manipulation example:
$(document).ready(function() {
var $grouplist = $('#groups');
$.each(myData, function() {
$('<li>' + this.name + '</li>').appendTo($grouplist);
});
});
# http://jsfiddle.net/qmacro/NJMyD/
If you want to stay with the native functionality without frameworks, javascript offers native dom manipulation functions that may be browser dependant.
When you're adding a new <javascript> element to the body, it should be automatically registered.
Thanks to all.
I created such solution:
var scripts = [];
$(response).each(function(key, element){
if ($(element).is('script')) {
scripts.push(element.innerHTML);
} else {
$('test').append($(element));
}
});
$.each(scripts, function(key, element){
eval(element);
});

jquery and mootools conflict - one script works, another don't

Ok, I use mootools to display flash content through google maps and I work hard to make it work properly, so there is little chance to switch it to jQuery. On the other side, I see jQuery more useful to every other things so I'm trying to make it work together. That's for explanation. Now here is the code.
this jQuery script I use to show/hide animation and it works with mootools perfectly
<script type="text/javascript">
jQuery(document).ready(function() {
// hides the slickbox as soon as the DOM is ready
jQuery('#slickbox').hide();
// toggles the slickbox on clicking the noted link
jQuery('#slick-toggle').click(function() {
jQuery('#slickbox').toggle(400);
return false;
});
});
recently, I added scrit to animate flowing menu and I can't get it work. I've tried to apply noConflict, but it didn't work. Here is the code:
<script language="text/javascript">
var $j = jQuery.noConflict();
var name = "#floatMenu";
var menuYloc = null;
$j(document).ready(function(){
menuYloc = parseInt($j(name).css("top").substring(0,$j(name).css("top").indexOf("px")))
$j(window).scroll(function () {
offset = menuYloc+$(document).scrollTop()+"px";
$j(name).animate({top:offset},{duration:500,queue:false});
});
});
</script>
Error message is Uncaught TypeError: Object # has no method 'dispose'
Thank you very much.
Format your code this way, and there is no need to use noConflict(). Call jQuery.noConflict(); right after the jQuery and MooTools library have been loaded.
<script type="text/javascript">
(function($){
var name = "#floatMenu",
menuYloc = null;
$(document).ready(function(){
menuYloc = parseInt($(name).css("top").substring(0,$(name).css("top").indexOf("px")))
$(window).scroll(function () {
var offset = menuYloc+$(document).scrollTop()+"px";
$(name).animate({top:offset},{duration:500,queue:false});
});
});
})(jQuery);
</script>
This will encapsulate your code to a function, which will be passed the jQuery object. Anywhere you use $ inside that function it will reference jQuery.
Also, there is no attribute language with the value "text/javascript", it's the type attribute, which should have that value. Don't use the language attribute anymore.

Categories