HTML: loading for elements without a body
My usual way to do javascript transforms for multiple elements through jQuery:
<div class="cow"></div> <script> $(".cow").doStuff() </script>
However, this operation is fragile and fragile: it works under the assumption that the page is loaded only once. As soon as you start to get into Ajax and partial reboot, this kind of global transformation is completely destroyed. It also does not work if the server wants to do a different conversion for each element based on some data on the server.
I know that the actual onload
for non- body
elements does not work. One solution is to provide all identifiers / element classes and access them immediately using jQuery:
<div id="cow"></div> <script> $("#cow").doStuff() </script>
However, it is really dirty; I don’t like this at all, partly because every element that I give an ID pollutes the global namespace. I am currently giving the element an effective non-configurable identifier
<div id="id877gN0icYtxi"></div> <script> $("#id877gN0icYtxi").doStuff() </script>
based on random base64 numbers. However, all this seems like a giant hack: I can give the onclick
and onmousedown
and it is very simple to use their corresponding attributes, which then call the function to convert this to this
.
Now I know that onload
not working. However, is there a way to mimic its functionality? In particular, I want to be able to run javascript code that references a specific tag using this
without having to assign an ID tag to them.
EDIT: Essentially, I want something like
<input onclick="alert('moo')"/>
but for oncreate; my current use case is to populate input
or textarea
text, and currently I am doing:
<input id="id877gN0icYtxi"/> <script>$("#id877gN0icYtxi").val(...)</script>
where ...
is different for each input field and therefore cannot be easily done using the "global" jquery transform. On the other hand, I cannot just set the value
or the input
attribute when I create it, as it could be textarea
, and I don't know. I want to do something like:
<input onload="$(this).val(...)"/>
Which does not work, but I would like to. Again, ...
set by the server and is different for each input
tag on the page.
EDIT2:
I am well aware that jQuery is commonly used to convert entire documents to multiple elements in the same way. The fact is that in this case, each element is transformed in the manner defined for this element, which is dictated by the server. A specific use case - each field has its own content, pre-filled with $().val()
, and, of course, each field is filled with different contents. Giving each element a unique identifier and using jQuery to search globally to find that element again seems like an incredibly devious way to do something and, of course, breaks when you start the Ajaxing parts of your page and exit.
EDIT3:
In short, I want to be able to write
<div onload="javascriptFunction(this)"/>
and javascriptFunction()
triggered when a <div>
(either on the start page or inserted via ajax) and the <div>
is passed as a parameter. Just like onclick
will run javascriptFunction()
with <div>
as a parameter when clicking on the div, I want the same thing to happen, but when the <div>
was created / inserted into the DOM.
I am ready to accept any number of installation scripts in <head>
for this to happen. For the reasons stated above, I do not want to add <script>
tags after <div>
or add class
or id
to <div>
. Given these limitations, what is the best way to simulate the onload
attribute for elements without a body?
There is no such onload
in the DOM specification, however, the DOM Level 2 specification provides mutation event types so that you can notify of any changes in the document structure, including attr and text changes, currently only modern browsers support such events, and in Internet Explorer 9 this error.
However, you can use the DOMNodeInserted event
to track the document for any changes:
$(document).live("DOMNodeInserted", function(e){ $(e.target).val(...); });
You must be careful about using Mutation events, at least try to update! According to W3C:
Mutation event types have not yet been fully and compatible implemented in all user agents. A new specification is being developed with the aim of addressing use cases that solve mutational events, but in a more advanced way.
I assume that if you have a question, you can find a cross browser / jquery plugin for it, just in case, these links will help:
https://developer.mozilla.org/en/DOM/Mutation_events
http://help.dottoro.com/ljfvvdnm.php#additionalEvents
http://help.dottoro.com/ljmcxjla.php
It all depends on what tags you want to work with.
One thing to know is that jQuery allows you to select multiple elements at once, so when you do something like $('p')
, this object applies to all p
nodes.
Doing something like $('p').hide()
hides all nodes of p
.
JQuery selectors (at least) are just as efficient as the CSS selector, so you can do some nice semantic things in one line.
Imagine if you have something like a list of response fields for a comment section or something else:
----------------------------------------- Comment #1 blah blah blah blah blah [ Text field ] (Reply) ----------------------------------------- Comment #2 nyark nyark nyark nyark [ Text field ] (Reply) ----------------------------------------- Comment #3 ubadabuba [ Text field ] (Reply) ----------------------------------------- Comment #4 eeeeeeeeeeeeeeeeeeeeeeeeee? [ Text field ] (Reply)
So your DOM layout might look something like this:
<div class="comment" > <h1> Comment #1 </h1> <p> blah blah blah blah blah </p> <input /> <button >Reply </button> </div> <div class="comment" > <h1> Comment #2 </h1> <p> nyark nyark nyark nyark </p> <input /> <button >Reply </button> </div>
so if you want to update all input fields to fit the default text, you just need to see that CSS selector for your .comment > input
fields.
After that, JS appears on its own
$(document).ready(function(){ var inputs=$('.comment > input ');//references all the input fields defined by this selector inputs.attr('value','default text');//set the value of the text in the input })
Providing identifier elements does not “pollute the global namespace”; it is just a mechanism for referencing elements. You only need the identifier for the element that you intend to reference by identifier. Providing identifiers to other elements is not harmful, just unnecessary.
You can refer to elements according to a number of criteria, including the class and their position in the DOM (any method in the CSS selector pool, as well as DOM relationships - parent, child, sibling, etc.). The method you choose may have advantages and disadvantages depending on how you use it, there is no really “good” or “best” way to do this, just some methods will be better suited for some cases than others.
If you want to replace, say, listeners after replacing elements in the DOM, then to replace elements you need to take this into account. Event delegation is one of the strategies, there are others.