server side background, getting deeper and deeper into client side.
I've got a site with a lot of legacy that I'm new to, and I'm just trying to get a handle on how things are working/what's available.
Is there a way to have jquery tell me(for a page/pages) all its current info and any plugins it can/is use/ing, similar to what phpinfo does?
Some proof of concept how you can get names for all plugins
var plugins = (function() {
var plugins = [];
for(var plugin in jQuery.fn) {
plugins.push(plugin)
}
return plugins;
}());
var filterValue = ['constructor', 'init', 'add', 'parents'] // // you must add all standard methods here
filterValue.forEach(function(value) {
var position = function(value) {
return plugins.indexOf(value);
}
while(position(value) >= 0) {
plugins.splice(position(value), 1)
}
})
console.log(plugins)
You can use the following for jQuery
console.log( jQuery.fn.jquery );
To answer your question directly, No jQuery does not have a mechanism that lists installed plug-ins.
jQuery does not keep such a registry of installed plugins. The jQuery plugin mechanism is to just add a method to the jQuery prototype (right along-side all the other jQuery methods). So, there's no separate list of which methods have been added by some outside agent (e.g. a plug-in). In addition, there's no one-to-one correspondence between methods and a particular plug-in as a single plug-in could add multiple methods.
It would be possible to create a master list (for any specific jQuery version) of what methods are there by default and then enumerate a jQuery object to find out which methods have been added since then, but you'd have to create that master list ahead of time and store it or create the master list immediately after jQuery was loaded before any plug-ins were loaded.
You can always test to see if any specific jQuery plug-in is loaded by just checking to see if any of its signature methods are available on a jQuery object.
So, if you really just wanted to know which of 10 plugins happen to be available in any given page, you could write a quick function that would test for each of the 10 plugins (by looking for the existence of known methods in those plugins) and would return a list of the ones installed, but this has to be done with specific knowledge of each plugin as there is no "generic plugin identification mechanism" since a plug-in is nothing more than a piece of code that adds methods to the jQuery prototype. It doesn't actually have any identity of its own.
Related
I'm somehow stuck with this code:
$(function () {
$('[data-toggle="tooltip"]').tooltip()
});
I'd like to change it to pure JavaScript. I'm not sure how to call the tooltip function, I already have some ideas like:
var tooltips = document.querySelectorAll("[data-toggle='tooltip']");
for(var i = 0; i < tooltips.length; i++){
//this gives an error
tooltips[i].tooltip();
}
I'm able to get all the tooltips, but I cannot initialize them. If I write something like this:
$(tooltips[i]).tooltip();
Then it works, but I want to remove the jQuery dependency since this is the only jQuery section that I have. Any idea? I've been searching and I cannot find anything useful.
For the new Bootstrap 5, this will be the new option without jQuery:
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
return new bootstrap.Tooltip(tooltipTriggerEl)
})
More info: https://getbootstrap.com/docs/5.0/components/tooltips/
Note:
In Bootstrap 4, you cannot initialize the Tooltips without jQuery. Here is an example:
https://jsfiddle.net/30c6kmnL/
There is a dependency on the function/class Tooltip that cannot be called (from my knowledge) without jQuery (you might need to rewrite the entire Tooltip function/class). I got errors like this one:
Uncaught TypeError: bootstrap.Tooltip is not a constructor
If you know how to fix it, please do it on the Snippet and share your results.
Thought I'd throw an answer out there using JS that also targets Bootstrap 4.x. The below code snippet will initialize all tooltips on the page in Bootstrap 4.x.
If you're unfamiliar with JavaScript classes and constructors then you may have trouble catching why the initialization didn't work in the original question.
Classes & Constructors: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/constructor
Bootstrap 4.x —requires— JQuery (v3.2.1 slim at minimum) and the Tooltips component specifically require another library, Popper.js (v1.12.3 at minimum). However, the initialization can be written with simple JS (to call the JQuery based constructor for tooltips).
Note: the keyword new is missing from the OP's original question, this is needed to instantiate a new class instance for each element.
function setTooltips() {
let tooltips = document.querySelectorAll('[data-toggle="tooltip"]');
for(let i = 0; i < tooltips.length; i++) {
let tooltip = new bootstrap.Tooltip(tooltips[i]);
}
}
You could also use the mapping method shown by BS5 as it would still be calling the JQuery based constructor. As long as JQuery and Popper are present beforehand.
Also you don't necessarily need to save the instance into memory if you don't need to reference it later, just return it instead.
Preferably call this in a DOMContentLoaded event globally to target any tooltips on any page.
window.addEventListener('DOMContentLoaded', function() {
setTooltips();
}, false);
Bootstrap 5 does things differently, mainly dropping JQuery as a dependency in favor of more modern ES6 JS. Use Federico's answer for Bootstrap 5.x and up, which is the default example from the BS5 docs for initializing tooltips.
Bootstrap 5 is designed to be used without JQuery, but it's still
possible to use our components with JQuery. If Bootstrap detects
jQuery in the window object it will add all of our components in
jQuery’s plugin system...
See: https://getbootstrap.com/docs/5.0/getting-started/javascript/#still-want-to-use-jquery-its-possible
I'm using a plugin called jQuery pusher (https://github.com/salvan13/jquery-pusher) to create some ajax-navigation on parts of a site, however this plugin can only be initialized once and I need to be able to apply it to new content loaded via ajax.
My question: could this be solved somehow via namespaces or some other way to create multiple instances of the same function that would not override/interfere with eachother?
It's not really clear what you mean by the wording of your actual question, which I think is the source of your confusion.
It's true that plugin initialization can't be "deferred" in the same way that handlers can be deferred by jQuery, which applies the handler to a top-level element and filters the events from there. Plugins need to be initialized directly on the element:
$('#someElement').pusher();
or group of matched elements:
$('.someElements').pusher();
So, for elements added to the DOM later, such as via AJAX, you'd need to explicitly initialize them after adding them:
$('#someContainingElement').load('ajaxcontent.html' function () {
$('#someContainingElement .someElements').pusher();
});
Turns out for this particular plugin this is the solution: https://github.com/salvan13/jquery-pusher/issues/3
I've noticed that RequireJS creates script tags in the tag as it loads modules.
Is there anyway to configure RequireJS to "tag" those elements w/ a class or an attribute of some kind that I could later target w/ jQuery later on?
e.g.:
var $requireJsScripts = $('script.require-script');
--UPDATE--
Ok.. I think I can get by on this little workaround for now. Thanks to this answer for the breadcrumb on require.s.contexts._.defined. I'd still like to hear if anyone knows of a way to configure RequireJS to do something similar to what was laid out in the original question...
var loadedRjsModules = Object.keys(require.s.contexts._.defined);
var $scripts = $('script');
$scripts.each(function () {
if ($(this).data('requiremodule') && $.inArray($(this).data('requiremodule'), loadedRjsModules)) {
console.log(this);
}
});
Looking at the source code, I don't see how RequireJS would allow adding anything custom to the script nodes at creation. The routine that creates them has no provision for it. The code that fleshes them out upon creation does not support it either.
There's an onResourceLoad hook considered part of the internal API. It could be used with the code you've put in your question instead of relying on require.s.contexts._.defined, which as far as I know is fully private and subject to change without notice.
I have searched but have not been able to find any information. I know this isn't typical of jQuery however I need to appease our structure that we have for PHP and make that into the jQuery plugin per my boss.
Is there any way to extend the $.fn to add another name? For example
$.MyTools.useTool('piece of wood','cut');
or
$('#wood').MyTools.useTool('cut');
I guess MyTools would be the class and useTool would be the function. However I have done this in a plugin. We are wanting to have our plugin called MyTools and whenever you use a function in it you need to call MyTools.
Would it be better to do away with the plugin and just create a class?
Yeah, when I want to make a namespace (sort of) like that I do this for all my plugins:
(function( $ ){
if(!$.fn.MyTools) {
$.fn.MyTools = {};
}
$.fn.MyTools.useTool = function() {
// do stuff
};
})( jQuery );
It appears that is no way to do this, so I had to take a different approach and take the official plugin way method by doing $.GLCFormattingCurrency('remove', data);
At first I made a function that received a parameter and returned jQuery such as:
function getjQuery(window)
{
/*jquery code*/(window);
return window.jQuery;
}
But then I got an email form the review and they told me I have to use jQuery file with the original file name and completely unmodified.
I started to search for an alternative and found this solution, but there is no way it work.
jQuery object is created, but I can't find any elements. $("#id").length is always 0. With the previous method it was always found.
My current code (which doesn't work)
AddonNameSpace.jQueryAux = jQuery;
AddonNameSpace.$ = function(selector,context) {
return // correct window
new AddonNameSpace.jQueryAux.fn.init(selector,context||contentWindow);
};
AddonNameSpace.$.fn =
AddonNameSpace.$.prototype = AddonNameSpace.jQueryAux.fn;
AddonNameSpace.jQuery = AddonNameSpace.$;
The jQuery file is loading on my browser.xul overlay:
<script type="text/javascript" src="chrome://addon/content/bin/jquery-1.5.2.min.js" />
Am I loading in the right place?
How can I use jQuery to modify the content on a page (HTML) with the original jQuery file, is it even possible?
You need pass the e.originalTarget.defaultView on the second parameter on jquery..
If you don't jquery will use window.document, which is the window.document from the xul.
Use
gBrowser.addEventListener("DOMContentLoaded", function (e) {
$("#id", e.originalTarget.defaultView).length
}, true);
instead of
$("#id").length;
And, for avoid conflicts with other extensions don't use script in the xul page, use MozIJSSubScriptLoader.
Components.classes["#mozilla.org/moz/jssubscript-loader;1"]
.getService(Components.interfaces.mozIJSSubScriptLoader)
.loadSubScript("chrome://youraddon/content/jquery-1.5.2.min.js");
If you use this method, you load jquery only when you need, avoiding memory leak.
The preferred way to load it is with mozIJSSubScriptLoader so you don't collide with other's extensions. I'm not sure why you're having problems, I can use jQuery in my addon like $("#id").hide() with no additional code (although from the sidebar, now browser.xul).
Either way, this blog post provides a pretty good guide and even has an example xpi to download.