In your official documentation, please explain you MUST use a JQuery selector, not regular JavaScript
mccarthysean opened this issue · 5 comments
In your official documentation, please explain you MUST use a JQuery selector, not regular JavaScript, to select the table. This can really trip up newbies like me... I'd been told to use vanilla JavaScript where possible, while I'm learning, but I really wanted to use your JQuery plugin for sticky headers on Bootstrap 4 responsive tables on mobile devices. You haven't been a JS rookie for a long time, so you would never be stumped by something like this... ;)
I included a working example of what to do, and what not to do, here in the code snippet, to explain what I mean, but I'm sure you get it.
<!-- Load JQuery first -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<!-- Then load floatThead JQuery plugin -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/floatthead/2.2.2/jquery.floatThead.min.js" integrity="sha512-QhaSMfyPHtKHbg7e//C6Y/nmpflIM9PgmhZ/TR+BcbRaR9eYXzZRfuK5D9pnVlp+J5zWXu5ckVzX4ycOQy/jZA==" crossorigin="anonymous" referrerpolicy="no-referrer">
</script>
<script>
<!-- This WILL work! -->
console.log("Attempt 1, using $ variable and JQuery selector WILL work!");
var $tbl = $("#myTable");
$tbl.floatThead();
<!-- This will NOT work -->
console.log("Attempt 2, with normal variable will NOT work!");
var tbl = document.getElementById("myTable");
tbl.floatThead();
<!-- This WILL NOT work either -->
console.log("Attempt 3, with $ in front of variable will NOT work either!");
var $tbl = document.getElementById("myTable");
$tbl.floatThead();
</script>
getElementById returns an Element. I understand how this may be a point of confusion to you now - there's a lot to learn in web dev, especially early on! - but this isn't documented for the same reason that it's not documented that e.g. date.floatThead()
and event.floatThead()
and everyOtherPossibleKindOfObject.floatThead()
not being a thing isn't documented. The list of "objects which will not have this method" is infinite and there's nothing unique about this library that makes that special.
Bathos is correct, this request is outside the scope of this project :)
The problem that you have is that someone told you that you should be using native javascript DOM api and not jquery, but they didnt explain why you should be doing that (maybe).
There are a lot of people these days who think that jquery should not be used because the problem it was originally created to address no longer exists. That problem was DOM api compatibility between browsers. You couldnt really write native javascript code that would work on IE6, IE7, IE8 etc, firefox and chrome without detecting the browser and writing code specifically for that browser. You ended up with code riddled with if statements and different hacks for different browsers.
jQuery addressed this problem by creating a wrapper API for the native DOM api that handled all the hacky stuff automatically for you. It also did a few other things that people today forget about:
- The jquery API was more concise than the native DOM API, for example
.attr(...)
instead ofsetAttribute
,removeAttribute
etc. - the jquery API added a lot of sugar which let you do more stuff with less code. This is both good and bad, it makes you feel powerful, but it also lets a jquery expert write code that no one understands.
- It also made it possible to operate on Elements in aggregate instead of one at a time. This is really powerful because the the entire API is based on this principle. The "thing" that a jquery selector returns is something called a wrapped set of 0 or more elements. Yes it can have nothing in it, but you can still call methods on it, and they will do nothing.
- The API is fluent where possible. That is, things that would normally return undefined return the jquery object you are calling the methods on. For example setting the styles returns the object you set styles on.
So back to your request -
This library is a jquery plugin, which means that it adds functionality to every object that is returned by a jquery selector function. The value that is returned from $('#myTable')
is a class of type JQuery
which is that API wrapper for the DOM API. In this example the wrapped set will contain a single Element
with id myTable.
The thing that is returned by document.getElementById
is Element, which is part of the native javascript DOM API.
When you know this, it makes sense that the plugin will exist on the jquery object but not on the native javascript API of Element.
Another thing I should call out is that prefixing the variable name with $ is a convention that a lot of jquery programmers use to specify that the variable is an instance of a jquery wrapped set object. This is useful because javascript has no types and the only way to convey variable types is through naming conventions, documentation or reading the code.
The dollar sign is a valid character that can be used inside of a variable name in javascript, unlike characters like *
and #
(that has recently changed, but it wasnt the case in 2012). Anyway, the dollar character is kind of nice, short, and stands out and that is why the author of jquery decided to use it as the name of the selector function.
Jquery is really nice actually and I think that the people who want you to write pure native JS are all fools :) they forget the other reasons that made jquery a pleasure to write and insist on rewriting small parts of it in native js every time they need to do that thing again but cant because they dont have a nice wrapper DOM API.
@bathos: How would you write this without jquery:
$('#catman, .cats, span:contains("cats are cute")')
.find('.furry')
.css({
color: 'salmon',
backgroundColor: 'cornsilk',
border: '2px dashed blue',
})
.width(100).end()
.addClass('poop')
.append($("<div class='additionalCats'>more cats go here</div>"))
.find('.additionalCats')
.text('all cats are furry');
run this: https://jsfiddle.net/mqn4jvzu/5/
Is it readable? It is to me. I probably shouldnt use the .end()
method and just create a new variable for the original selector, but I want to be fancy shmancy :)
Also setting width using the method is likely not needed and should be done via css()
above. Historically the width method did the correct thing for the box-model your browser used, since IE's was different (as usual).
Re: the kinda rhetorical question for me - translated to native platform methods, that would be very verbose, enough that I'm not gonna try to translate for real.
Looked at individually, a lot in the example does have a pretty direct equiv or contextually near-equiv, e.g.
addClass(x) -> elem.classList.add(x)
text(x) -> elem.innerText = x // *usually*
append(x) -> elem.insertAdjacentHTML('beforeend', x)
$(x) / find(x) -> node.querySelectorAll(x) // *usually*
css(x) -> Object.assign(elem.styles, x)
One doesn't (the jQuery DSL's :contains()
selector).*
But - and I assume this is what you wanted to illustrate to the OP - all of these APIs are only equivalent (or similar) when it comes to an individual selection or mutation. There is no native equivalent to the "wrapped set" concept, which means writing scripty imperative code to "do some stuff once based on selectors" is much better served by jQuery - that's what it's for, and it's good at it.
A lot of front end dev doesn't use this idiom and may not benefit from jQuery at all. But whatever idiom you're writing in, it is not bad in itself to leverage libraries appropriate to what you're doing, and jQuery is nowhere near being a "top offender" when it comes to bloat, so I agree that folks shouldn't be afraid of it. (It won't stop you from learning the platform, if that's the concern - there are some idioms that tend to do that, but this isn't one of them; when using jQuery, there's no "penalty" for going "outside jQuery" as needed.)
* It does have an analogue in XPath, but that doesn't count.
Thanks guys. Appreciate all the feedback! Go ahead and close this issue if you like.
I was really just thinking you might want to add one or two sentences to your main website page, for complete JavaScript/JQuery newbies... That's all. I've noticed quite a few questions on StackOverflow regarding FloatThead plugin installation as well. I know it's been a long time since you were JavaScript rookies ;)