What is the purpose of the with_jquery function?

15

I'm learning to write UserScripts (for TamperMonkey ) and pretty much all the examples I see make use of a with_jquery function:

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 particular 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 ( $ ) within the script, but this example works the same way in SOpt, with or without with_jquery :

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

    
asked by anonymous 06.10.2016 / 17:32

1 answer

14

You can manually add files with the .user.js extension to the chrome://extensions/ tab (in chrome, other browsers based in Chromium might not work):

  

Click the image to see the animation:

     

It'sasifChromehadtheGreasemonkeynative(Ibelievethat'sright).

However,directlyinstalledscriptswithouttampermonkeywillnotallowdirectaccesstothevariablesdefinedbythepage,onlynativevariablesareaccessible.Soifyour.user.jstriestodirectlyaccess$,jQuery,window.$andwindow.jQueryitwillreturnundefined.

Howeverifyouinjectascriptviadocument.createElementusingstringitwillgetaccess,soforthisreason"(" + f.toString() + ")(jQuery)"; , it converts the function to string and injects into the page.

  

/ p>

Another possible situation is to avoid conflicts with $ in different javascript libraries that use it, for example if the site uses the library YUI that can overwrite the variable $ , so the use of (jQuery); instead of directly access.

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

In addition also this function can also be used for things like:

  • Many userscripts make use of jQuery
  • People need to run a userscript only on pages with jQuery, type to fix or modify jQuery behaviors or even make a proxy type on it.
  • In order to detect if jQuery has already been loaded, if it is not, it stays in a loop waiting for jQuery to be loaded (this depends on who writes the userscript)

Note that on network sites only use jQuery, but a userscript can be used on different sites, even if you create it for a specific site or designed to be used on different sites on purpose.

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 the jQuery to the context of the calling function, it is not really necessary, but let's say it is a proxy that affects the behavior of jQuery or because N reasons there is some context problem of the functions, this would eventually store inside the context current, without needing to access the global (in the window. case) directly and avoid conflicts with multiple libraries

For example, assuming 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 $ is the argument of a callback:

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

It will be a variable other than $ global (which is the same as window.$ ), if 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, because YUI will probably overwrite $ , but what you expect is to use jQuery instead of YUI, if you use it directly, then the conflict problem may occur :

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

But if you do this:

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

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

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

So you can keep using $ to refer to jQuery, even if another lib affects the overall.

    
06.10.2016 / 17:36