How to select multiple jQuery objects? - javascript

Like if I wanted to select both document and window elements.
$(window, document).doStuff();
Doesn't work. Probably because according to the docs, 2nd argument is some "context" thing...
Basically I'm just looking for an alternative too
$(window).doStuff();
$(document).doStuff();

var one = $("#1");
var two = $("#2");
var three = $("#3");
var four = $("#4");
$([one, two, three, four]).each(function() {
// your function here
});
The document ready event executes already when the HTML-Document is loaded and the DOM is ready, even if all the graphics haven’t loaded yet.
If you want to hook up your events for certain elements before the window loads, then $(document).ready is the right place.

$(window).add(document).doStuff();

Related

is jquery .one() computing checks every event?

And therefore adding a bit of computing load?
For those of you unfamiliar with the .one() jquery function it basically triggers an event just once. Such as if you wanted to add a div on the first time a page is scrolled.
To bring background to the matter, I came across this question:
How to alert when scroll page only first time using javascript?
I have been in projects where I had to add hundreds or thousands of events, so for me it’s always very important to optimize computing power, plus, I am a curious person so I just need to know.
One of the answers where the guy uses vanilla javascript is basically an endless loop where you switch a boolean on the first instance and basically have to continually enter the function to see if it has been already triggered.
var xxx;
$(window).scroll(function () {
if(!xxx)
{
xxx = true;
var div = $("#myDiv");
alert(div.height());
}
});
My idea is that jquery being already heavy on the page it probably just performs this same action under the hood, but I would like to be completely certain as for my future implementations.
No. jQuery's .one works similarly to, for example:
calling addEventListener, and then, in the callback, calling removeEventListener
calling addEventListener with { once: true } in the options object
in jQuery, like calling .on, and then, in the callback, calling .off
Once the listener runs once, it's de-attached; no further logic takes place when the event occurs in the future, because the listener is no longer connected at all.
So .one is very light on computing resources, even if you add lots and lots of .ones.
You can see the source code of one here:
if (one === 1) {
origFn = fn;
fn = function (event) {
// Can use an empty set, since event contains the info
jQuery().off(event); // <-------------------------------------------------
return origFn.apply(this, arguments);
};
// Use same guid so caller can remove using origFn
fn.guid = origFn.guid || (origFn.guid = jQuery.guid++);
}
return elem.each(function () {
jQuery.event.add(this, types, fn, data, selector);
});
where jQuery() returns a jQuery collection containing elements matching the current selector. When one is called, the callback is wrapped in another that calls .off as soon as the function is executed.
The sample code in the answer you linked to is quite inefficient, and should not be used, especially for scroll events, which fire very frequently.

Why is document.getElementById("item").value so hard to assign to a variable?

The way I see it, something like var thingy = document.getElementById("item").value should create a variable, put this element's value in it, and call the element's value whenever the variable is called.
I understand that it's not so simple, but I don't understand why.
I've read a lot of similar questions considering global variables and page onload.
The page unload seems to explain why linking the HTML page to an external javascript file, but I don't understand why there isn't a simple solution to that.
What makes assigning a variable to the element of an external HTML document so complicated that people commonly resort to jquery's simple $() assignment?
Keeping a "live" reference to an element
var thingy = document.getElementById("item").value is copying the value when the line is executed and storing it in thingy.
To keep a "live" copy of the value you would store a reference to the element
var thingy = document.getElementById("item")
Then you can call later
thingy.value to get the current value.
this is comparable to how it sounds like you have been using jQuery
var thingy = $("#item")
using var thingy = $("#item").val() would produce the same behavior as before of copying the current value and subsequent calls to thingy would not be the "live" value.
Having that reference be not null
Out of the box script tags are parsed synchronously, aka right when they are hit by the parser. Any elements after your script will not be loaded nor be available for querying.
I believe jQuery hooks into the DOMContentLoaded event and fires your code once the DOM tree is fully available(all the elements have been parsed). They give you some shorthands for hooking into this event.
$(function(){})
$(document).ready(function(){})
jQuery(function($){ });
The same is achievable in vanilla.js by hooking into the DOMContentLoaded event
document.addEventListener('DOMContentLoaded', function(){
/* DOM tree fully parsed and available here */
});
HTML 5 introduced the defer attribute to the script tag so we don't have to worry about it at all, our external script will be called after the DOM is parsed. Note that this only applies to external scripts and does not work with internal
<script src="mysite.js" defer></script>
....
/* inside mysite.js */
//DOM ready good to go
var thingy = document.getElementById("item");
Most likely you are facing this problem because you are trying to get the element before the dom is fully loaded, whilst jquery work inside function.ready so it waits for the page to be ready
When we type out var thingy = document.getElementById("item").value You're just getting the current value at that moment. That makes sense because it would be extremely hard to manipulate values and dom elements when the values always changing.. When you always want thingy to always return the current value you need a function.
var thingy = this.getValue();
getValue(){
return document.getElementById("item").value;
}
What makes assigning a variable to the element of an external HTML
document so complicated that people commonly resort to jquery's simple
$() assignment?
Nothing. It's just preference.
Edit: Check #Proffesor Allmans answer for more details to your problem. You have to post some code for a solution though.

Resize event for multiple elements at different times

I have a situation where different elements need to be re-sized by JavaScript when the window is re-sized.
Currently for each element I am simply attaching a new event like so:
window.addEventListener('resize',function(){ self.resize(MyEl);}, false );
I'm starting to think this isn't a smart idea, because say i have to resize 50 elements, i am currently attaching 50 events (gross exaggeration, but you can see how it isn't a smart design). Not to mention, when i remove the element, the event is still there!
So i am wondering what would be a better way to handle the resize event so it will then process different resize functions that i define but can equally remove said functions when they are no longer relevant.
What is considered a good approach for something like this so i then only need one event attached.
I would use an object to map an element to function. For example:
var toResize = {'#banner': self.bigResizer, '.ads': self.smallResizer};
Then you can easily dynamically add/remove elements and their resize function.
toResize['#footer'] = self.bigResizer;
delete toResize['#banner'];
Then in your event handler you'd do something like:
for (var sel in toResize) {
if (toResize[sel]) {
toResize[sel].call(self, document.querySelector(sel));
}
}
I think, adding separate events for each element is the correct approach compared to what I will explain below. The reason is that browser will run the event function when its time comes, so the browser won't freeze.
Also, I am sure you know it already, you can remove the event function if it was a single function instead of anonymous function. So, turning the system into that style would be helpful.
Another approach, but this might freeze your browser whenever the window is resized.
Define an array. Each item of array is an htmlElement.
var elementsToBeResized = [];
Define a single function that receives the resize event for elements.
function element_resize( elIndex ){
var htmlElement = elementsToBeResized[ elIndex ];
if( !document.body.contains( htmlElement ) ){
elementsToBeResized[ elIndex ] = null;
return;
}
// ... do your resizing things ...
}
When window is resized, call a function that loops over the array elementsToBeResized. And instead of adding new event, either replace a null item in elementsToBeResized, or append it.
But do not forget, because all events are called sequentially without a break, it might create freezing issue as I am telling third time.
You can simply resize all the elements in one event handler.
The list of elements would need to be maintained in global object of some form though.
Using jQuery, for example:
var $all = $('div')
$( window ).resize( function(){
$all.each(function () {
console.log($(this).attr('class'));
// individual element resize logic goes here e.g.
// $(this).myresizefunc();
})
});
jsfiddle here:https://jsfiddle.net/jsheridan390/aLdap6j8/

jquery basic of dollar sign - named vs anonymous

I have a couple of interview questions
What is the different between $(function(){}); and $(document).ready(function(){});
What is the difference between $(function(){}); and var func=function(){}; How are each of them called?
Given the following script
<script language="javascript">
$(function()
{
var id=$("cssID");
//do something with your id
//your event to be added here
});
</script>
How can you add an event, say, onmouseout that will work on the id?
Here are my answers:
They are the same, both are meant to run when the page document finishes loading
The first one is called automatically while the second one will be called via named reference; that is func.called(), for example.
Something like this:
$(function()
{
var id=$("cssID");
//do something with your id
//Oki
id.onmouseout
(function(){
//do something
});
});
However my professor says I was wrong in all three. she explained things I am unsure and didn't dare to ask, she was mad about me. What are the correct answers and why are mine wrong?
These are the different types of Document Ready functions typically used in jQuery (aka jQuery DOM Ready). A lot of developers seem to use them without really knowing why. So I will try to explain why you might choose one version over another. Think of the document ready function as a self-executing function which fires after the page elements have loaded.
See Where to Declare Your jQuery Functions for more information on how to use the Document Ready Functions.
Document Ready Example 1
$(document).ready(function() {
//do jQuery stuff when DOM is ready
});
Document Ready Example 2
$(function(){
//jQuery code here
});
This is equivalent to example 1… they literally mean the same thing.
Document Ready Example 3
jQuery(document).ready(function($) {
//do jQuery stuff when DOM is ready
});
Document Ready Example 4
(function($) {
// code using $ as alias to jQuery
$(function() {
// more code using $ as alias to jQuery
});
})(jQuery);
// other code using $ as an alias to the other library
Document Ready Example 5
$(window).load(function(){
//initialize after images are loaded
});
Here is the link for you to refer.
1. They are the same, both are meant to run when the page document finishes loading
This is half right. They are the same, the first is just a shortcut way to write the second, but they don't run when the document finishes loading, they run when the DOM is ready (at which time some resources such as images might still be loading).
2. The first one is called automatically while the second one will be called via named reference; that is func.called(), for example.
Again half right. In the first one the anonymous function will be called automatically when the DOM is ready as per question 1. The second example can be called with func(). You wouldn't have the .called part in there. Or you can pass func as a parameter, e.g., as $(document).ready(func).
Q3
var id=$("cssID");
How can you add an event, say, onmouseout that will work on the id?
$("cssID") creates a jQuery object that will contain zero or more elements depending on how many matched the "cssID" selector. The id variable references that jQuery object. If the question is how to assign an event handler to those matching elements you'd do this:
id.mouseout(function() { /* some code */. });
// OR
id.on("mouseout", function() { /* some code */ });
When processing events with jQuery you don't use "on" in the event names, so it's "mouseout" not "onmouseout".
So your answer to 3 was nearly right.
(Note though that "cssID" is a selector that won't actually match any elements unless you have <cssID> tags in your document...)
There is no difference between:
$(functionValue);
And:
$(document).ready(functionValue);
So your professor is wrong there. The second example is completely different. One of them runs on document ready and requires jQuery; the other one is just a function literal assigned to a JavaScript variable.
As for the third one, you'd probably do it with on. onmouseover is correct if you use get, but not really the best way of going about things, and you definitely wouldn't call it like you're doing there - that's completely incorrect.
id.on('mouseout', yourHandler);
or
id.mouseout(yourHandler);

JavaScript Inline Events or Adding Events Afterwards

I have a question, which I can't seem to decide on my own so I'll ask here. The question is simple: whether to use inline JavaScript events or adding them afterwards? The theory in the background isn't that simple though:
I have a JS object that returns HTML. Whenever you create this object, the returned HTML will be used for another object's HTML. Therefore, adding events is not straight-forward. See:
secret.object = function() {
this.init = function() {
var html = '<div>and lots of other HTML content</div>';
return html;
};
}
This is a sample object that is created within this code:
for ( var i = 0; i < countObjects; i++) {
var obj = arguments[0].content[i];
generatedContent += spawnSecret(); /* The spawnSecret() is a method that initializes the object, and calls its init() method that returns the HTML.
}
and then later on I create a new object whose property "content" will be set to "generatedContent". It needs to add the events within the secret object I have, nowhere else. And since my system is built like this, I see only two ways around this: use inline events or build HTML using method calling instead of returning.
Hopefully, this wasn't too hard to understand.
If you created the elements using document.createElement() (but didn't append them to the DOM) and kept a reference to them, then you could populate them with the text content and attach event handlers to them, without having to use inline events.
When you are ready to reveal your 'secret' you could then append them to the DOM, rather than dumping in a text string of HTML tags and content.
I cant see it making much of a difference - if you just render your events using onclick etc. JavaScript event handlers they will be evaluated as soon as you append your generated HTML to the document, rather than you having to call attachEvent() or whatever.

Categories