jQuery plugin's $ collides with jQuery's $ - javascript

I have 3 js files, call them myJavascript.js, myPlugin.js and the jQuery libary.
The files themselves are relatively long, so I try to convey the issue without copying the entire scripts.
In the html file using them, I've included the js files in the following order:
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.2.1.min.js"></script>
<script src="resources/js/myPlugin.js"></script>
<script src="resources/js/myJavascript.js"></script>
I've written the plugin in the following structure:
myPlugin.js :
(function ($) {
local variables...
//several functions with the form
$.fn.funcName = function(parameters) { body };
//several function used internally
function funcName(parameters) { body }
}(jQuery));
In myJavascript.js, I'm using only methods defined in the plugin (just like using jQuery methods), and it's working. However, when I tried to invoke a jQuery method (authentic one, not from the plugin) before invoking plugin function, I got the error:
Uncaught TypeError: $(...).mazeBoard is not a function
To give a concrete example:
/* when this block exists, the call to mazeBoard throws the error */
/* when I remove this block, the call to mazeBoard works perfectly */
{
$(function () {
jQuery("#navigationMenu").load("nav.html");
loadSettings();
});
}
/********************/
{
...local variables...
function getSingleGame() {
...body...
$.getJSON(url, function (data) {
//this is some function in myJavascript.js
var mazeData = makeMazeData(data.Maze, data.Rows, data.Cols);
//this is call to function from my plugin
mymaze = $('#mazeCanvas').mazeBoard(mazeData);
alert('success');
}).fail(function () {
alert('error!');
});
}
}
Anyone knows what's the problem? If everything seems to be fine, I'll try to add more details.

Related

Overiding functions defined in an external script

I am trying to write some userscripts in JavaScript to be used with browser extensions.
In a website, I tried overriding a function defined in an external javascript, with Object.defineProperty. but it seems that this breaks the external script, because other codes in the external scripts (that are essential to the original website) seems to be not executing as well.
<html>
<head>
<!-- injected script, injected via Userscript -->
<script>
Object.defineProperty(window, 'originalFunction', { get: function() { return overridingFunction; } });
</script>
<!-- injection end -->
</head>
<body>
<script src="/external-javascript.js">
<script> originalFunction(); </script>
<script> anotherEssentialFunction(); </script>
</body>
</html>
and http://domain/external-javascript.js looks like this"
...
function originalFunction() {
some codes here;
}
...
function anotherEssentialFunction() {
....
}
and this was preventing anotherEssentialFunction from running. In the console, I see TypeError: can't redefine non-configurable property originalFunction and ReferenceError: anotherEssentialFunction is not defined
Is this expected in this situation, or there should be other problem causing it that is not described here? How can I safely override original function without causing such an error?
Object.defineProperty takes the name of a function as a parameter, so you'd have to do this instead:
Object.defineProperty(window, 'originalFunction', {
get: function() {
return overridingFunction;
}
});
Or if that's all the getter does, simply:
window.originalFunction = overridingFunction;
But if the other functions need to call the original function, you can't really override it without breaking the functions that rely on its behavior. If you're just trying to execute custom code in addition to the original code, you can do this:
var origFn = window.originalFunction;
window.originalFunction = function () {
customFunction();
origFn.apply(this, [].slice.call(arguments));
};
Update:
Based on your comment, it sounds like you're wanting to not only override the original function but also prevent the external script from redefining that function. You can maybe add a no-op setter to avoid the external script from getting an error when trying to define it:
Object.defineProperty(window, 'originalFunction', {
get: function() {
return overridingFunction;
},
set: function(ignored) { }
});

How to access a function which is not global and it exist in another js file?

I have the following js files and I want to access one function from another function but I call it in another js file. I receive this error when I call it Uncaught ReferenceError: vidPause is not defined.
(function($) {
$.fn.controlls = function(opt) {
......
function init() {
.....
}
function vidPause(e){
e.stopPropagation();
$.fn.controlls.toggleBarPlayingButtons('pause');
video.pause();
}
.....
From this js file I want to call vidPause in the following function in another js file
function myFunction(e) {
if (video) {
$('video').controlls(vidPause());
This issue is scope.
init() and vidPause() are private to the (function($) { call. They will not be directly accessible the way you are trying to access them.
Many jquery plugins use text (not my preference, but that's how they work), eg $.dialog("open"), so you could do something like that (not sure if opt is meant to mean action, so update accordingly) :
(function($) {
$.fn.controlls = function(action, opt) {
switch (action) {
case "pause":
vidPause(opt);
break;
...
usage
$('video').controlls("pause");
It might be possible to add the methods as if using namespaces, but I've not seen this in plugins so depends on what you are doing with your plugin (ie releasing it) whether you want to be consistent, eg:
(function($) {
$.fn.controlls = {};
$.fn.controlls.pause = function(opt) {
video.pause();
...
usage
$('video').controlls.pause()

How can I use a javascript function globally in Drupal 7

How can I use a javascript function globally in Drupal 7.
I have my javascript file set up like this and add it using drupal_add_js():
(function($) {
function add_if_country_is_not_usa() {
// Check what country it is
// Update text, image, etc.. of a block.
}
});
In my block WYSIWIG I added the following code (The reason I add it in the WYSIWIG is because I want it to update before the page is fully rendered):
<script type="text/javascript">
add_if_country_is_not_usa();
</script>
But I get the following error:
Uncaught ReferenceError: add_if_country_is_not_usa is not defined
(anonymous function)
I read about adding functions to Drupal behaviors but that happens on document ready. I want to run the function as soon as the block is shown.
Any ideas?
Either define in the global scope, or do like below:
(function($) {
function add_if_country_is_not_usa() {
// Check what country it is
// Update text, image, etc.. of a block.
}
// set as a property of the global object `window`
window.add_if_country_is_not_usa = add_if_country_is_not_usa;
});
Not sure if this is the best way but I ended up being able to get it work using a namespaces. I call myGlobalObject.add_if_country_is_not_usa() from my block and it works now.
var myGlobalObject = mySingleGlobalObject || { 'country': {} };
(function ($) {
myGlobalObject.country = '';
myGlobalObject.add_if_country_is_not_usa = function() {
// Check what country it is
// myGlobalObject.country = 'US';
}
})(jQuery);

calling a method which is in different file

In my project, I have two js files which are as follows:
file1.js
(function($){
jQuery(function(){
jQuery.user = {
getAnchorUrl : function (el){
return jQuery(el).attr('href');
}
}
});
})(jQuery);
file2.js
(function($){
jQuery(function(){
jQuery('.popup-video-link').on('click', function(e){
e.preventDefault();
var url = jQuery.user.getAnchorUrl(this);
jQuery.user.getVideoPopupTemplate(url);
});
});
})(jQuery);
I am loading file1.js first then file2.js.
Whenever I click the anchor tag which has class .popup-video-link, I am getting error
TypeError: jQuery.user.getAnchorUrl is not a function
Any help where I am going wrong?
PS: I am wrapping the jquery code because in this project I am also using prototype.js and many other plugins.
Remove jQuery(function(){ from file1.js. Try this:
(function($){
jQuery.user = {
getAnchorUrl : function (el){
return jQuery(el).attr('href');
}
}
})(jQuery);
When using jQuery(callback) the call back is loaded when the page is loaded (like $(document).ready(callback), almost), (callback)(jQuery) creates an anonymous function which is then called with the first parameter as jQuery

method is not defined in Javascript when I use Web Logger for iOS

It's really strange when I try to dump logs to the Web page.
I have basic application (in xcode) with Web plugin that allows me to pull logs from iPhone to web page.
But, somehow, when I try to call method placed in other js file, I get:"method" is not defined.
xcode-Web structure:
Snippets of socket.html:
<script type="text/javascript" src="src/js/script.js"></script>
<script type="text/javascript">
$(document).ready(main);
// Run when document.ready fires
function main() {
$('#btnClear').click(function() {
clearTable();
});
}
....
</script>
The clearTable is method defined in src/js/script.js file and I know its loaded because onLoad method has called.
Snippets of script.js:
$(function() {
....
function onLoad(){
....
}
function clearTable(){
....
}
onLoad();
});
Does someone know the reason?
I coped this project to linux and all work fine. All dependences work good.
Thank you,
It is because of scoping issue, clearTable is defined within an anonymous function so it will be available only within that scope.
You are trying invoke it from another scope where it is not available.
The solution is to define the clearTable in the global scope. ex
$(function() {
// ....
function onLoad() {
// ....
}
window.clearTable = function() {
// ....
}
onLoad();
});
Problem: Fiddle
Solution: Fiddle
Another solution
var clearTable, isAutoScroll; //Declare these as global variables
$(function() {
// ....
function onLoad() {
// ....
}
//note this is a function variable and there is no `var`
clearTable = function() {
// ....
}
//note there is not `var` used while defining the variable
isAutoScroll = false;
onLoad();
});

Categories