I have created a page that use jquery ui tabs and each tab load a page via ajax request.I have cached result of ajax request.My problem is inner javascript in my pages that loaded in tabs.For example I have linkClick function in both pages, when I am opening these pages linkClick function override with second method.
How I can separate these method in my project.
Sincerely you Mahmood Bagheri
Use a namespace and a closure for your code/application.
Something like this:
(function (global) {
var MYAPP = {};
MYAPP.linkClick = function () ....
global.MYAPP = MYAPP;
})(this);
Then whenever you need linkClick, you use MYAPP.linkClick and it does not get mixed with other names.
This way you avoid name collisions.
It is very bad way to define functions in such way. Make functions less specific and add parameters, this functions preferably should be located in one file which should be loaded with other libs.
Related
What I need is pretty simple, although I don't know if possible..
I'm attaching all my event handlers to the object themselves instead of to $(document).
But, I need to attach them on the .ready() method, to make sure the object is created before the handler is attached. Since there are a lot of handlers to attach, to keep my code cleaner I want to create a function called attachHandlers() that will be called on document.ready().
But.. this function should execute codes that are in multiple files.
My question is.. is there a way of declaring the same function multiple times, and then calling it just once to execute them all?
But.. this function should execute codes that are in multiple files.
My question is.. is there a way of declaring the same function
multiple times, and then calling it just once to execute them all?
If interpret Question correctly, you want to request javascript from multiple files at .ready() . You can create an array containing url of file to request, use $.when(), $.map(), $.getScript() to call the javascript within the files
jQuery.getScript( url [, success ] ) Returns: jqXHR
Description:
Load a JavaScript file from the server using a GET HTTP request, then
execute it.
The script is executed in the global context, so it can refer to other
variables and use jQuery functions. Included scripts can have some
impact on the current page.
$(document).ready(function() {
var files = ["1.js", "2.js", "3.js"];
$.when.apply($, $.map(files, function(file) {
// request file
return $.getScript(file)
}))
.then(function() {
// complete
// do stuff
}, function err(jqxhr, textStatus, errorThrown) {
// handle error
});
});
Create a global JS file that has this function (and future functions that you want to be run on all pages). Call this script at the top of each file in the head element. Calling it in the head should do what you need (at least that is what i use in my projects and works for me).
Can u package your multiple files in modules and every one of them has a method attachHandlers? Then try use requirejs to load all of them. In document.ready, call the attachHandlers method from all these modules? It will be neater
I have a coding difficulty which have been asked in this forum before:
Calling a JavaScript function returned from an Ajax response
But I didn't find the answers quite satisfying. To be more precise of the problem I'm dealing, here is the detail:
I dynamically load a document (HTML and javascript) using jquery
var url = 'document.php';
$('#container').load(url);
Example of what the document.php looks like:
<form>
<input name="firstname"></input>
</form>
<script>
function dosomething()
{
console.log($('input[name=firstname]').val());
}
</script>
*The dosomething() function is the one I'd like to call later
And then I want to call the functions from that document.php. Due to my requirement, I don't want to call the function after the documents' loaded, but rather to call it later when I need it. Because it was dynamically loaded, the DOM doesn't recognize the functions. How to properly call this function?
Thank you
the DOM doesn't recognize the functions
This sounds like your other functions are wrapped in $(document).ready() in the remote page. If that is the case they are out of scope for you to call them from code in the main page and you need to move them out of the ready handler to make them globally accessible.
EDIT: Other possibilities
Script tags in head- move to body after html, or use $.getScript in ajax callback to retrieve
I think that you're trying to implement the technique called on-demand javascript (or lazy-loading). In other words, your page should initially load just a small script - but use a bunch of objects and functions, which are available in some other files, but will be loaded when they're required.
If that's the case, I have to warn you: you'll probably need to update your existing code. Instead of just calling some function right as it is, in all gun-blazing glory, you should check for its existence first - and if it's not available, wait for its loading:
if (typeof lazyObjects.someLazyFunction !== 'function') {
lazyLoad('lazyFunction.js');
}
lazyObjects.someLazyFunction();
The key point here is that lazyLoad should be synchronous. In other words, you'll have to wait until the script containing your function is actually loaded. Otherwise someLazyFunction just won't be defined when it's called, even with this sort of checks.
lazyFunction.js, in turn, will contain some code that will alter lazyObjects, adding to them the required method as a property:
// in lazyFunction.js
lazyObjects.someLazyFunction = function() { ... }
While it's technically possible to use global (=window) object for these cases, I usually don't do this - and won't recommend doing it either.
See, it's not that simple. ) I'd recommend reading this article to find out more about this technique - and actually using some established components to implement it in your code (some of them are mentioned in the linked article).
Just wanted to know if it was a good JavaScript practice.
Let's say I have many Web pages that all call an initialization function "init()", would it be the right thing to use an IIFE inside my pattern to run the function everytime the script is loaded?
var foo = (function() {
var bar = "something";
(function init() {
// Do something crazy that's gonna be the same across all my web pages
// like adding an event listener or something
// ...
document.write('page init...');
}());
function privatePage1() {
// This stuff is gonna be used only in page1.html via foo.privatePage1
document.write('page 1' + bar);
}
function privatePage2() {
// This stuff is gonna be used only in page2.html via foo.privatePage2
document.write('page 2' + bar);
}
return {
privatePage1: privatePage1,
privatePage2: privatePage2
}
}());
This is a pretty subjective area, but here's my take:
When you use the module pattern, you're providing a contained set of functionality to the rest of your code. It's essentially a mini-library.
In general, I wouldn't expect a library to do anything when I load it, other than initialization steps that are entirely internal to the library (e.g. setting up the configuration, instantiating a few necessary objects, etc) - nothing that actually affects the DOM or otherwise significantly alters the environment (which is why I've never been entirely comfortable with libraries like Date.js or Prototype that change the prototypes of basic objects).
There are a couple of reasons for this, but the main one is that I don't want to have to worry about the load order of my libraries/modules, other than simply managing dependencies. Independent modules shouldn't affect each other at all. When you manipulate the DOM in your module at load time, sooner or later you'll realize that another piece of your code is expecting the DOM to be in a certain state at a certain time, and that you now have to care about whether you load your module before or after that time. This is an extra bit of complexity that's essentially hidden in the script tag that loads your module.
The other issue here is portability and adaptability. Maybe you'll want to use your module in another project with another DOM setup. Maybe you'll want to pass a different DOM element or config variable to the init() function on a specific page. If you execute init() automagically, you lose the opportunity for configuration.
So what I generally do is to set the init() method as an attribute of the returned module object:
var foo = (function() {
function init() {
// Do something crazy that's gonna be the same across all my web pages
}
//...
return {
init: init,
// etc
}
}());
and then call it as needed elsewhere in my code:
foo.init();
Yes, this adds an extra line of redundant code to the initialization for all my pages (though this is probably just one other script anyway, so the added weight is all of 11 characters). But it allows me a more fine-grained control over when the module is initialized, and offers a hook for configuration arguments when I (inevitably) determine I need them later.
Is the init() function the same across web pages? If so, this is what I'd do:
var foo = (function()
{
init();
return {};
}());
If not, I don't see a reason to use an IIFE, and would simplify your original code like so:
var foo = (function()
{
/* body of the original IIFE here */
return {};
}());
I have a WordPress theme and I'm using a few jQuery plugins within it. The problem is that some of these plugins are included in other WP plugins, so the js breaks because of naming conflicts.
I was wondering if there is a way to somehow isolate a set of functions or a .js file from the rest of the scripts that are being included in the HTML document.
something like:
function wrap(){
plugin functions...
plugin functions...
}
jQuery(document).ready(function($){
wrap.pluginfunction()...
wrap.pluginfunction()...
});
The easiest way to do this is to wrap the whole script like this:
var someNewNamespace = (function () {
// Script goes here
// If you want to expose functions on the namespace:
var that = {};
// Declare a new function to expose:
that.someFunction = function () {
// ...
};
// Expose a function declared previously:
that.someOtherFunction = someFunctionDeclaredPreviously;
return that;
}();
This will effectively create a new namespace for the script. The someNewNamespace object will have members like someFunction etc. after this executes. Any variables declared within the anonymous outer function, but not exposed via the that object will be inaccessible from outside of the script.
jQuery has a noConflict() method so it won't kill other libraries.
Just call jQuery.noConflict(); after loading the jquery library and you should be set.
UPDATE: The back-end service was powered by an ASP.Net AJAX Web Service proxy.
1) The main page has two global objects, one for the back end connections (Svc) and another for handling the DOM (Main). It also dynamically loads documents into an iframe.
2) These iframes need to access services provided by Svc, and also supply a callback function.
3) The problem - passing a function created in the iframe to the parent frame, it's treated as an object not a function and cannot be invoked.
Can anyone provide a better solution than what I've got currently in the iframe:
var Main = parent.Main,
Svc = parent.Svc;
Svc.method(data, Main.createCallback(
function(response) {}
));
and in the parent frame:
Main.createCallback = function(func) {
return function() {
func.apply(func, arguments);
}
}
if you override the iFrame's function from the main, the main scope will then be used.
The inverse problem can be seen here, in your case, you just override the frame's function itself i.e:
document.getElementById('yourFrameID').contentWindow.targetFunctionInFrame = targetFunctionInMain;
Bonus: if you can modify the iFrame's code, I would suggest to:
In the frame:
make a placeholder function callbackParent() {}
add a call to this function into your iframe code, so that you just have to override the callbackParent from your main.
In the main:
make the function which should be invoked function doStuff() {}
override the function as described above document.getElementById('yourFrameID').contentWindow.callBackParent = doStuff;
I use iframes to modularize my app too.They are a kind of includes embedding all CSS, HTML and JS for a module.
My first attempts were by returning a function too, but then I found it quite hard for sharing scopes.
Now I make directly a reference to the main parent object in the iframe.
eg:
var Svc = parent.Svc, JSON = parent.JSON, $ = parent.$;
Svc.module1 = {
method1:function(arg){
...
},
...
}
The global var JSON and jQuery references are here to have them available inside the methods.
My guest is that Svc.method is making some checks to see if the callback has some criteria before calling it. This criteria might be that the callback function must created by the same framework (here it's ASP.Net). You have to find what that criteria is. if "Main.createCallback" works, it's because it's meeting that criteria.
Sorry but your all wrong... add this....
const event = new CustomEvent('MSGSent', { detail: "fff variable" });
Call it like this....use a global variable for detail... like an array []
window.dispatchEvent(event);
Now after the iframe loads add this code and you get an Object back in the main page....
iframe.onload = function() {
try {
iframe.contentWindow.addEventListener('MSGSent',function(e){
alert(e.detail);
});
} catch (error) {
}
};
The problem is ASP.Net AJAX Web Service proxies, which don't appear to support calling the web service from an iframe with an inline callback function.