What is the purpose of the with_jquery function?

Asked

Viewed 676 times

15

I’m learning to write Userscripts (for Tampermonkey) and virtually every example I see makes use of a function with_jquery:

function with_jquery(f) {
   if (!jQuery)
      return;

  var script = document.createElement("script");
  script.type = "text/javascript";
  script.textContent = "(" + f.toString() + ")(jQuery)";
  document.body.appendChild(script);
};

Although the scripts are different, the implementation of this specific function is always the same. With the rest of the script being invoked making use of it:

//Declaração de with_jquery()

with_jquery(function($){
    // Resto do UserScript
});

My initial impression was that this served to give access to the jQuery object ($) inside the script, but this example works the same way in Sopt, with or without using the with_jquery:

var bar = $("#h-top-questions");
bar.append("teste");

inserir a descrição da imagem aqui

1 answer

13


You can manually add files with the extension .user.js to the tab with address chrome://extensions/ (on Chrome, other Chromium-based browsers may not work):

Click on the image to see the animation:

Greasemonkey nativo no Chrome

It’s like Chrome has native Greasemonkey (I think that’s right).

However scripts installed directly without tampermonkey will not allow direct access to variables defined by the page, only native variables are accessible. So if in your file .user.js try to access directly $, jQuery, window.$ and window.jQuery will return undefined.

However if you inject a script via document.createElement using string it will get access, so for this reason "(" + f.toString() + ")(jQuery)";, it converts the function to string and injects it into the page.

Note: In the tampermonkey for Chrome/Opera is not required as it allows direct access to any tab variable, apparently Greasemonkey also allows direct access currently


Other possible situation is to avoid conflicts with $ in different javascript libraries that use it, for example if the site uses the library YUI which can override the variable $, therefore the use of (jQuery); instead of accessing directly.

Note that this type of technique is not only used in userscripts, it is used by jQuery plugins too.

Also this function can also be used for things like:

  • Many Userscripts make use of jQuery
  • People need to run a userscript only on jQuery pages, type to correct or modify jQuery behaviors or even do a proxy type on it.
  • To detect if jQuery has already been loaded, if it is not looped, waiting for jQuery to be loaded (this is according to who writes userscript)

Note that on the web sites only use jQuery, but a userscript can be used on different sites, even if you create it for a specific site or developed to be used on different websites purposefully.

Explanation of the code:

function with_jquery(f) {
   if (!jQuery) // <-- Verifica se existe jQuery na página, ou seja ele já foi carregado
      return; // <-- Se não tiver sido carregado

  //Se o jQuery estiver disponivel na página que o userscript é injetado então a partir daqui carrega o script solicitado

  var script = document.createElement("script");
  script.type = "text/javascript";

  //Passa a variavel jQuery para o escopo do callback para evitar conflitos com outras bibliotecas no uso do $
  script.textContent = "(" + f.toString() + ")(jQuery)";


  document.body.appendChild(script);
};

And this line specifies:

"(" + f.toString() + ")(jQuery)";

Pass jQuery to the context of the called function, it’s not really necessary, but let’s say it’s a proxy that affects the behavior of jQuery or for N reasons there is some context problem of the functions, this would eventually store within the current context, without needing to access the global (in this case window.) directly and avoid conflicts with multiple libraries

For example, suppose the site uses jQuery and YUI, the object $ may conflict, so we usually use $.noConflict();, but we can also move to the context of the function, ie if $ being the argument of a callback:

with_jquery(function($){ //<-- aqui
    // Resto do UserScript
});

It will be a different variable from $ global (which is the same as window.$), if by chance another script or userscript loads a lib like YUI that uses $ in the global scope, it can rewrite the variable $ causing your userscript to stop working, as probably YUI will override the $, but what you expect is to use jQuery and not YUI, if you use directly so may occur conflict problem:

$(".foo").bar();

But if you do so:

with_jquery(function($){
    $(".foo").bar();
});

You will be accessing the same as the jQuery variable which would avoid conflict with other libs like YUI, and you will not need to write the code in a long way:

jQuery(".foo").bar();

Thus being able to maintain the use of $ to refer to jQuery, even if another lib affects the global.

  • 1

    Good. I didn’t know about the other libraries that use $, and this explains well the need to clarify the reference to jQuery in the with_jquery. Thanks.

  • @Gabe updated response, there were details that did not know about the Chrome browser.

Browser other questions tagged

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