How to call a function of another JS file keeping the context of the current function?

Asked

Viewed 6,436 times

5

I have the following scenario:

HTML:

<script src="JS1.js">
<script src="JS2.js">

In JS1 I have the following:

$(document).ready(function(){
   var pagina = "site1";

   iniciarSite();
});

In JS2 I have the following:

function iniciarSite(){
   if(pagina == "site1"){
       alert("Estou no site 1");
   }
}

The error is that the page variable does not exist in this context.

  • 4

    There is no way to do with local variable, only with global or passing values from one function to another.

  • If in the first JS I put before Document.ready a varivael page, it can be accessed by start site?

  • @Joaopaulo Sim.

  • 3

    @Joaopaulo His function iniciarSite is global. If you create var pagina out of any function, it will also be global. Etc. If you provide the JS2.js will define a lot as global, it may be worth creating a single object to "concentrate" all variables and functions defined/used by this script, not to pollute the namespace.

  • Only if the var pagina is on the "outside". Or else, instead, window.pagina = "página";

  • 1

    What’s wrong with doing iniciarSite(pagina);? defining the function: function iniciarSite(p){ if(p == "site1"){ // etc

  • The problem is, I want to pass a lot of parameters. Then I put inside an object: Parametros.pagina; Since this function of the second js is huge and I would have to rename a lot of things.

  • 1

    @Joaopaulo then and why not pass an object as an argument of the function? I think you need to show more (or all) what you intend to do or else you will have answers that will not hit the problem because you are leaving important details out...

  • 1

    Another thing in line with what @Sergio said: if you have control of the two files, should the functions really be divided between them? Would it not be the case to have an object in which the functions would be methods, and the variables would be properties?

Show 4 more comments

2 answers

4


You must declare the variable globally.

var pagina;
$(document).ready(function(){
    pagina = "site1";
    iniciarSite();
});

or

$(document).ready(function(){
    window.pagina = "site1";
    iniciarSite();
});

Another alternative is to pass the variable per parameter.

2

I do not recommend using global variables. Let’s look at some possibilities to avoid this.

Solution using an object as parameter

An object { ... } is a flexible way to pass multiple parameters when needed, as if it were a map.

$(document).ready(function(){
  iniciarSite({
    pagina: "site1",
    outroAtributo: 10
  });
});

function iniciarSite(args){
  if(args.pagina == "site1"){
    alert("Estou no site 1");
  }
}

Solution using a global state

I do not consider an elegant solution, after all it is still a global variable, but it is better to put all the "garbage" in one place than to have "loose" and "spread" variables throughout the code.

var pageConfig = {
  pagina: "site1" //valor default
};

$(document).ready(function(){
  //necessário apenas se o valor mudar durante a execução
  //pageConfig.pagina = "site1"; 

  iniciarSite();
});

function iniciarSite(){
  if(pageConfig.pagina == "site1"){
    alert("Estou no site 1");
  }
}

It’s a kick, but I believe the Javascript file that defines the value of the variable pagina is a specific file included in a specific HTML, while the other Javascript file is a general file included in several pages.

If so, the following example would be something more appropriate:

Specific file:

//define as propriedades da página atual
var pageAttributes = {
  pagina: "site1"
  /*Outras propriedades da página*/
};

General archive:

//lê propriedades da página específica e inicializa o site
$(function() {
  if (pageAttributes) { //verifica se existem propriedades, caso contrário não faz nada
    if (pageAttributes.pagina == "site1") {
      alert("Estou no site 1");
    }
  }
});

In the above example, the object pageAttributes stores page-specific settings. This wouldn’t even need to be in a separate Javascript. This type of information can go inside the HTML itself.

Just don’t forget that the specific script should always be included before the general script.

Do not check the page

A more drastic solution, but one that I consider more flexible and appropriate, would be not coding pages, but components on the page.

This means that instead of a code that "knows" which page it is on, it would be better to have a code that "reacts" properly on any page.

How to do this? There are several ways.

Imagine a scenario where you want to decorate your tables with Data Tables plugin, using the command dataTables(). The problem is that only search screens have tables.

At first you could do something like this:

function iniciarSite(args){
  if(args.pagina == "pesquisa-paises"){
    $('#tabela-paises').dataTables();
  }
  if(args.pagina == "pesquisa-estados"){
    $('#tabela-estados').dataTables();
  }
  if(args.pagina == "pesquisa-municipios"){
    $('#tabela-municipios').dataTables();
  }
}

However, we could generalize this very easily using a special class, for example decorate-dt. With a small modification in the tables (<table class="decorate-dt">) our code could end like this:

function iniciarSite(args){
    $('.decorate-dt').dataTables();
}

It would always run and do nothing in case it does not find tables with the CSS class.

What if it was necessary to customize one or another table with specific parameters? Just use attributes data-* in the corresponding tags, then all the configuration is in HTML, no script needed.

Plugins recognized as Datatables and Bootstrap Javascript plugins have native support for this type of structure.

For your own routines, use the function jQuery.data() to read the specific settings.

Incidentally, even if you want to keep checking which page you are could still use this technique. Put a date attribute in your (<body data-pagina="site1">) and then access the attribute. Example:

function iniciarSite(args){
    var pagina = $('body').data('pagina');
    if (pagina  == "site1") {
      alert("Estou no site 1");
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.