In d3.js, numerous calls to modify aspects on all elements in a given selection can be chained like so:
mySelection.attr('someAttribute', function retrieveSomeAttributeValue (d) {
return d.someValue;
}).style('someCssProperty', function retrieveSomeCssPropertyValue (d) {
return d.someValue % 2;
});
Now, both retrieveSomeAttributeValue and retrieveSomeCssPropertyValue will be called once for each element in mySelection.
However, is their order of execution for any given element also specified? I could not find anything explicit on this in the docs. Concretely: For any given element in mySelection, is retrieveSomeAttributeValue guaranteed to be called before retrieveSomeCssPropertyValue because the attr call surrounding the former precedes the style call surrounding the latter in the call chain?
In general terms: Are modification functions such as attr and style applied in the order they are chained?
EDIT: As there seems to be some confusion about the scope of my question, I will try to clarify: Obviously, the attr function is invoked before the style function. But does attr apply its changes to each element, and then return the resulting collection, whereupon style applies its changes to each element? Or do, for instance, attr and style somehow add their respective modifications as pending changes on the collection object, to be executed in a possibly different order at a later time?
EDIT2: As this question appears to generate some confusion, please use the comments area to ask for clarification if anything in particular is unclear.
When it comes to fiddling with the DOM tree D3 tends to be implemented pretty straightforward without having to resort to any kind of hidden magic. Many calls to D3's methods will more or less directly delegate to native DOM interfaces. Methods like .attr() and .style() are no exception to this general assessment.
Since documentation may hide the inner workings of a library from its reader and user, the best way to assure yourself of the way D3 does this stuff is probably to dig into its source code. As an example let us have a look at selection.attr().
According to the docs:
# selection.attr(name[, value]) <>
[…] otherwise, if the value is a function, it is evaluated for each selected element, in order, being passed the current datum (d), the current index (i), and the current group (nodes), with this as the current DOM element (nodes[i]). The function’s return value is then used to set each element’s attribute.
This describes the method's usage as a setter by providing two arguments to the call: the first being the attribute's name, the second being the callback. The relevant part of the method's full source look like this:
return this.each((value == null // <== For all nodes in this selection...
? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function"
? (fullname.local ? attrFunctionNS : attrFunction) // <== ...set to callbacks return value.
: (fullname.local ? attrConstantNS : attrConstant)))(fullname, value));
Based on how to handle namespaces (fullname.local) it will call the appropriate function attrFunctionNS or attrFunction. Both of which look quite similar:
function attrFunction(name, value) {
return function() {
var v = value.apply(this, arguments); // Evaluate the callback.
if (v == null) this.removeAttribute(name); // Standard method call.
else this.setAttribute(name, v); // Standard method call.
};
}
The function returned from this call will execute the callback (referred to by value) on its first line. Based on the value returned from that call it will either remove the attribute if that value equals null or it will set the attribute's value to the callback's return value. Both these operations make use of the two standard DOM API methods Element.removeAttribute() or Element.setAttribute(), respectively.
As can easily be seen from these few lines, D3 does not make any use of hidden magic or intrinsic state but directly forwards to native DOM methods. For this same reasion you are guaranteed that your callbacks will get called for every node in the selection in the very same order as they are chained.
Always because a call to attr(), style() , append(), filter(), .... return a selection that the next call operates on. This selection can be different of the selection the call operates on.
Before the return the callbacks (if defined) are called for every element in the selection. There is no asynchronous stuff happening behind the scenes.
Related
I'm using a function to create other functions that will be used on an document event handler so the signature of the returned functions must match that of the event handler, eg. function (event, ui).
The code is as follows
function createEventHandler(refFn, additionalMods) {
var createdEvent = function (event, ui) {
// Merge the properties of additionalMods with an object { event, ui }
// call function with refFn and the resulting object as parameters
}
createdEvent.ready = true;
return createdEvent;
}
I removed the code of the generated function for clarity but inside the refFn and additionalMods variables are processed inside.
Now when processing the user input I call the following line
var handler = events[i].handler.ready ?
events[i].handler :
createEventHandler(events[i].handler);
Basically process an array of data that each has a property called handler which is either a function or the result of calling createEventHandler.
The bottom line is that if the function in the array has been processed then pass this function 'as is', if not process the function and store the result so in the end all the functions are processed.
Right now i'm attaching a property called ready to signal that the function was processed as it turns out there is no reliable method to obtain the function's name according to this post but this doesn't feel right.
I also tried to use the prototype for comparison but this doesn't work because a new function is created everytime and is inside a scope so I can not get a reference for comparison.
I even tried
events[i].handler.prototype == createEventHandler().prototype
but of course it didn't work.
Does anyone know how can i generate this functions and have a reliable way to compare them to know if they were generated by my code or not.
{Edit}
To add further clarification
All the code above is under the same scope meaning the code that process the array has visibility over the createEventHandler function. I can modify this code all I want what I cannot modify is the content of the array once is created. I have to iterate over it as it comes and generate or not based on if the work was done already.
The createEventHandler is also exposed to the user throught an API function. Let's say the user calls evt.generate('model') this will generate an event handler that does an specific work using the createEventHandler function under the hoods. If then you can call evt.generate('bind') another will be generated that does another work.
This is a lot of behaviour that is provided to the users by default but they can choose to add they custom behaviour if none of the predefined ones are fit for the task.
All the data is declared once but the content of the array is disparate because I can write the following and is supposed to work. I omitted most of the other irrelevant properties.
var events = [
{
event: 'pageshow',
handler: evt.generate('model')
},
{
event: 'pagebeforeshow',
handler: function (params, last) {
// My custom handler for this case
}
}
];
After looping the array all the handlers are in the same format and ready to be binded. The createEventHandler is necessary in all the cases because I use dependency injection to supply data for those parameters so it's basically "if not called already then call it and do al the dependency injection work" this is why I need to compare the functions.
I found an elegant solution and I post it here in case someone runs into the same problem.
The problem with my code is that an user car write a function with a property named ready which is a common name and a value of true which is also a common value and the processing will fail.
Maybe the user didn't write the property, maybe is present because is inherited from it's prototype. The goal is to try to be as certain as possible that the code you are processing was the output or your own functions or not, which in javascript is almost an impossible task.
The most accurate way that I found was when I was reading about Equality comparisons and sameness which tells me that an object is only equal to itself when you use the === equality operator and is not a primitive object. That is
undefined === undefined => true
null === null => true
"foo" === "foo" => true
0 === 0 => true
But
{a:1} === {a:1} => false
So you can write a property ready which is equal to an object and as you hold the reference to that object all the comparissons will fail if this property was not set by you.
This is good but it feels bad to have an extra property called ready with a random object just to compare, maybe there is a better way and yes, there is.
In javascript there are no classes but there is prototype inheritance so you can write a function and use one of the patterns of inheritance to set this function as the ancestor of yours and use that for comparisons.
var parentEvent = function () {};
// This is the function that will be used as parent
function createEventHandler(refFn, additionalMods) {
var createdEvent = function (event, ui) {
// Merge the properties of additionalMods with an object { event, ui }
// call function with refFn and the resulting object as parameters
}
//createdEvent.ready = true This is no longer necessary
// This is the "sharing prototype" inheritance pattern
createdEvent.prototype = parentEvent.prototype
return createdEvent;
}
Now the prototype of your returned function is pointing to a function that you hold in a variable. Then you can compare them using
// Replace the property comparison with the prototype comparison
var handler = events[i].handler.prototype === parentEvent.prototype ?
events[i].handler :
createEventHandler(events[i].handler);
This is not fail proof, I know, but is good enough for most cases.
{Edit}
Thank's to #Bergi for pointing out that this is not inheritance in the strict sense of the word. The reason for that is that most javascript inheritance patterns demand that you use constructor functions and I'm using a factory function here. To make it work you have to write something like this
function createEventHandler(refFn, additionalMods) {
// Same code as before
createdEvent.prototype = parentEvent.prototype
return new createdEvent();
}
And the comparison is done with
events[i].handler.__proto__ === parentEvent.prototype
Note the difference in the way the function is returned ant the way the new prototype property is accessed. This is good when you do have other properties that you want to return that are in the parent function.
Do the contents of the events array change during the execution of your program, aside from replacing them with the converted versions?
If not, a simple solution is just to make a copy of the handlers before you start converting them, and use that for the comparison:
// keep this somewhere that you can access it later
var origHandlers = events.map(function (e) { return e.handler; });
var handler = events[i].handler === origHandlers[i] ?
createEventHandler(events[i].handler) :
events[i].handler;
I was trying to determine the best way to observe a variable's value and track its changes, for example 'language' or 'time-zone', then when it will be changed take some actions depending on the new value.
I thought of using setInterval, but I have many 'interval's in my website, so I don't want to overuse it, I'm worried that it may affect the user experience. Instead I found my self compelled to trigger the actions which I want to be done after the value changes in each method may change the variable's value, this is simple but makes my code a bit tightly coupled.
what do you suggest for that.
It seems like Object.observe would be pretty much exactly what you need; unfortunately it is currently proposed as a "post ECMAScript 6" spec, so it will be a while until it is widely available in browsers. There are shim implementations though (e.g. here or here), which could give you the same functionality in current browsers.
An alternative approach would be wrapping the object in question in a direct proxy, but those are part of ES6, and also not widely adopted by browsers yet.
In languages like C++, you'd do this with accessor methods.
For example, instead of accessing a property of a class with something like foo.bar, you'd say foo.getBar().
getBar() would look something like this:
this.getBar = function(){
console.log("bar was accessed");
return bar;
}
You should also have a method to set the value of bar, i.e.
this.setBar = function(newBar){
console.log("Setting the value of bar");
bar = newBar;
}
These methods will give you more control of your variables, too. For example, if someone tries to assign a string to something that should be an integer, you could throw an error. Or if you have a variable called "length", you could throw an error if someone tries to make it less than zero.
You should use Object.prototype.watch() to track variable's change
The watch() method watches for a property to be assigned a value and
runs a function when that occurs.
Watches for assignment to a property named prop in this object,
calling handler(prop, oldval, newval) whenever prop is set and storing
the return value in that property. A watchpoint can filter (or
nullify) the value assignment, by returning a modified newval (or by
returning oldval).
If you delete a property for which a watchpoint has been set, that
watchpoint does not disappear. If you later recreate the property, the
watchpoint is still in effect.
To remove a watchpoint, use the unwatch() method. By default, the
watch method is inherited by every object descended from Object.
there is not standard, but you can use the gist polifill created by eli-grey
Anyway this is a duplicate of Listening for variable changes in JavaScript or jQuery
This a theoretical question:
Is there a generic name to refer to all those jQuery functions that don't accept functions as a parameter?
Such the index(), children(), height() ...
UPDATE:
If i know the name then I could make a question like this: "Can I pass a function to a "named" function?"
To give a little more detail, I have tried to pass a function as a parameter to jQuery's .index() method but it does not work:
textbox.closest('tr').index(function(){var index = $(this);});
All jQuery functions that take parameters can take functions. In JavaScript, functions are objects, and neither jQuery or vanilla JavaScript are type-safe. In other words, as long as the function accepts parameters, it will accept a function as one of its arguments.
Ergo, methods that do not accept any parameters are the only methods that will not accept functions.
EDIT:
If you want to get technical, then even methods that do not accept any parameters will still accept a function as an argument. Just as JavaScript isn't type-safe, it also doesn't actually enforce any rules regarding the function's signature, i.e. it doesn't check that the number of arguments entered matches the number of arguments defined. This is why you get a "null reference" error (if unhandled) instead of a "no function [function name] takes the arguments [arguments list]". This is also why you can pass an unlimited number of arguments to a function, even if it only takes one, two, or none.
UPDATE:
With regards to my solution to your original question, I would like to clarify by adding that jQuery is a solid language in that it often will simply return null when it is passed invalid arguments (but it will not error out when being passed an incorrect number of arguments). JavaScript is the same in many situations, but, as I implied and common sense would dictate, it would be nonsensical to pass too many or too few arguments to a method, regardless of legality.
With regards to your updates and your comments, I think that you're misunderstanding the fundamental use of jQuery's .index() method. When used properly, this method is called on a collection of elements and has a selector (or an element to match) as a parameter, and returns the index of the first occurrence of an element that satisfies the given selector, or matches the given element.
Update:
From your updated example, I can see that I was correct in thinking that you are misunderstanding the use of the .index() function a little bit. The function takes either a selector or an element, but you passed a function that doesn't return either. Here is what you would need (using your existing syntax):
textbox.closest('tr').index(function(){ return $(this);});
OR (more simply):
textbox.closest('tr').index($(this));
To add a bit more detail (and, perhaps, better answer your initial question), you could also do something like this:
function getOnlyParagraphElements() {
return this.tagName === "p";
}
var collection = $("body").find("*");
var firstParaIndex = collection.index(getOnlyParagraphElements);
This was only an example (and yes, I know that I could just use jQuery to get paragraphs), but the concept is the same - this is how you make your own selector.
Also note that in your examples, you are always checking against a one-item collection, meaning you will only get either the value 0 or the value -1 (if the element doesn't match the selector/passed in element). If your goal is to get the index of the element that you are calling the method on relative to its siblings, then you need only call the method without supplying any parameters.
I'm currently reading through this jquery masking plugin to try and understand how it works, and in numerous places the author calls the slice() function passing no arguments to it. For instance here the _buffer variable is slice()d, and _buffer.slice() and _buffer seem to hold the same values.
Is there any reason for doing this, or is the author just making the code more complicated than it should be?
//functionality fn
function unmaskedvalue($input, skipDatepickerCheck) {
var input = $input[0];
if (tests && (skipDatepickerCheck === true || !$input.hasClass('hasDatepicker'))) {
var buffer = _buffer.slice();
checkVal(input, buffer);
return $.map(buffer, function(element, index) {
return isMask(index) && element != getBufferElement(_buffer.slice(), index) ? element : null; }).join('');
}
else {
return input._valueGet();
}
}
The .slice() method makes a (shallow) copy of an array, and takes parameters to indicate which subset of the source array to copy. Calling it with no arguments just copies the entire array. That is:
_buffer.slice();
// is equivalent to
_buffer.slice(0);
// also equivalent to
_buffer.slice(0, _buffer.length);
EDIT: Isn't the start index mandatory? Yes. And no. Sort of. JavaScript references (like MDN) usually say that .slice() requires at least one argument, the start index. Calling .slice() with no arguments is like saying .slice(undefined). In the ECMAScript Language Spec, step 5 in the .slice() algorithm says "Let relativeStart be ToInteger(start)". If you look at the algorithm for the abstract operation ToInteger(), which in turn uses ToNumber(), you'll see that it ends up converting undefined to 0.
Still, in my own code I would always say .slice(0), not .slice() - to me it seems neater.
array.slice() = array shallow copy and is a shorter form of array.slice()
Is there any reason for doing this, or is the author just making the code more complicated than it should be?
Yes there may be a reason in the following cases (for which we do not have a clue, on whether they apply, in the provided code):
checkVal() or getBufferElement() modify the content of the arrays passed to them (as second and first argument respectively). In this case the code author wants to prevent the global variable _buffer's content from being modified when calling unmaskedvalue().
The function passed to $.map runs asynchronously. In this case the code author wants to make sure that the passed callback will access the array content as it was during unmaskedvalue() execution (e.g. Another event handler could modify _buffer content after unmaskedvalue() execution and before $.map's callback execution).
If none of the above is the case then, yes, the code would equally work without using .slice(). In this case maybe the code author wants to play safe and avoid bugs from future code changes that would result in unforeseen _buffer content modifications.
Note:
When saying: "prevent the global variable _buffer's content from being modified" it means to achieve the following:
_buffer[0].someProp = "new value" would reflect in the copied array.
_buffer[0] = "new value" would not reflect in the copied array.
(For preventing changes also in the first bullet above, array deep clone can be used, but this is out of the discussed context)
Note 2:
In ES6
var buffer = _buffer.slice();
can also be written as
var buffer = [..._buffer];
I'm trying to understand the format of the Javascript functions that jQuery, among other people, use.
For instance jQuery(arg).hide() or $("#obj").hide
I'd like to write similar format functions but I don't understand how.
I know how to write
function myFunc(args) {
}
but I don't understand the second part ie the .hide()
is that a function within a function?
thanks for any help
It's called method chaining. The way to achieve this is for your first function to return an object, so the second function can be called as a method on that object.
The standard way to do this style of programming is to always return the same type of object, so for example, jQuery always returns a jQuery object representing a collection of HTML nodes. If one of the calls modifies the collection then the next call will be on that collection. That's how you can do something like $('#myid').parent().hide();. $('#myid') returns a jQuery object representing the #myid element and .parent() returns a jQuery object representing the parent element of #myid. .hide() returns the same object, so you could then call another method on the same object if you wanted.
This is called method chaining. I highly recommend picking up Crockford's "JavaScript: The Good Parts". This is a very quick read but wonderfully explains OOP in JavaScript and identifies good versus bad language features. Highly recommend it.
As Skilldrick pointed out, this is called method chaining.
The most straightforward example for this is an object that returns itself when you call any of its methods:
var world = {
'hello': function() {
alert('Hello');
return this;
},
'goodbye': function() {
alert('Goodbye');
return this;
}
};
world.hello().goodbye();
This is identical to world.hello(); world.goodbye();.
jQuery does a little more than that. Calling the jQuery or $ function on a valid selector string will return a jQuery object representing the matched elements (it's not actually an array, though you could think of it as one). Most of its methods will return the object itself after modifying the object (e.g. $("a").css({...}) will apply changes to the styling of the matched elements and then return the set of matched elements again).
But some jQuery methods allow modifying the set you're working with (e.g. $("a").parent() will return a jQuery object representing the parents of the matched elements). That is, they don't return the same object, but an object that behaves identically.
You have to be careful if you decide to use this style, though, as the flow will break if you need a method that has a return value of its own (e.g. if you want calculations or getter methods). This can be avoided by passing a callback function to the method, but the resulting coding style may be terribly convoluted.