I am wondering if it is better to put your html in javascript or in your html files.
For example having my js file have this
$('<div>').addClass('test').append(
$('<p>').text('test1'),
$('<span>').text('test2'),
$('<span>').text('test3')
).insertAfter( $('#test1') );
VS
My html file looking like this
<div id="#test1"></div>
<div class="test">
<p>test1</p>
<span>test2</span>
<span>test3</span>
</div>
and the js file have:
$('.test').show();
Highly subjective and depends on contexts of course.
In a web page, most of the content is already known. No reason not to just put the content in the HTML and use CSS (and maybe Javascript when really needed) to style in.
In a web application, however, things are not so well known. The document is much more dynamic and using Javascript to add/remove elements is required.
BTW, your two pieces of code do two different things. In the first example you give it a class of test and in the second you are giving it an ID of #test1. This is an invalid ID and should be test1. The selector for that ID would be #test1 which may be causing some of the confusion.
This is probably okay for just straight-up webpages, but for web applications you should really look into a templating system such as mustache.js(https://github.com/janl/mustache.js) or Handlebars.js(http://handlebarsjs.com/).
That way, you can keep your HTML in external template files and use Javascript objects and arrays to fill them with data. For example, a mustache template might look like:
<div id="{{id}}"></div>
<div class="{{class}}">
<p>{{name}}</p>
<span>{{prop1}}</span>
<span>{{prop2}}</span>
</div>
And you would have an object that looks like this to fill it:
var obj = {
id: "myID",
class: "some classes",
name: "Martin Brennan",
prop1: "whatever",
prop2: 22
}
And you would use the template with the object like this (after loading the template into a variable):
Mustache.render(template, obj)
Like Jeremy J Starcher said though, this is highly subjective, and I would suggested that you give templating systems a try to see if you can see the value in using them in your project(s).
Of course the second option is much better and faster.
If you use
$('<div>').addClass('test').append(
$('<p>').text('test1'),
$('<span>').text('test2'),
$('<span>').text('test3')
).insertAfter( $('#test1') );
browser must parse JavaScript. And each time you use $() you are creating an object which has a lot of properties and methods which you don't use (useless!). And of course the browser must parse the HTML too.
But if you use
<div id="#test1"></div>
<div class="test">
<p>test1</p>
<span>test2</span>
<span>test3</span>
</div>
browser only has to parse HTML and it's much faster.
One of the largest benefits of using the 2nd, hard-coded HTML method is that it'll still show up for people with JavaScript disabled. It's hard to verify exactly how many users don't have JS enabled (because most trackers use JS..) but last guesstimate I heard was somewhere around 5% of internet users.
Moral of the story - make your site work without JavaScript. Then and only then add JavaScript to make it look prettier/ add additional (non essential) features.
The simple answer is that static content should be created using normal markup, while Javascript should be used for dynamic content.
Also, in many cases you can use both. You can have static HTML markup with style="display:none", and then use Javascript to change the style to make it appear and disappear as needed.
Related
I'm a front-end developer, and I'm worried about the best way to target my DOM.
Let's imagine a tiny form to create a new zombie :
<h1>Add a new zombie</h1>
<form id="create-zombie">
<input id="zombie" type="text" name="zombie" />
<input id="lvl" type="text" name="lvl" />
<button type="submit">Add</button>
</form>
...and if I want to get the values of zombie and lvl, I will code something like this:
class Zombie_Add extends Controller
# Dom References
el:
'form': '#create-zombie'
'zombie': '#zombie'
'lvl': '#lvl'
run: ->
#on 'submit', #el.form, #validate
validate: (e) =>
e.preventDefault()
zombie = $(#el.zombie).val()
lvl = $(#el.lvl).val()
module.exports = Zombie_Add
That's "ok" and it does the job, but I have some problems with that "structure" :
If somebody touches the DOM and removes an ID, I'm just fucked, it breaks my code (Captain Obvious spotted !)
For more complicated selectors, it's just a mess (I'm thinking about some stuff like that [name^="dummy-"] input:first). I guess it's easy to imagine how shitty the names of el are.
Anyway, what I want to learn today is what's the best way to target the DOM from JS. Is it better to use IDs, class values or, data-* attributes? How we can prettify a selector with plain English, etc...
If somebody touches the DOM and removes an ID, I'm just ****ed, it
breaks my code (Captain Obvious spotted !)
The best way to target a single, unique element in the DOM is with an ID like you are doing with zombie and lvl. It is both fast to execute and simple to code.
It is a given that if someone messes with the id values in your HTML, that will break your Javascript. That's just the way it is. Anyone messing with your HTML has to be smart enough to know that an ID value is there for a reason so if they want to change that or remove it, then it is their responsibility to find someone who can make corresponding changes in the Javascript. That's just the way it is.
For more complicated selectors, it's just a mess (I'm thinking about
some stuff like that [name^="dummy-"] input:first). I guess it's easy
to imagine how ****ty the names of el are.
The same goes for more complicated selectors. Like it or not, a modern web page is a melding of server-side stuff, presentation HTML and Javascript. The three have to work together to deliver the final solution. While you strive to avoid unnecessary dependencies with good design techniques and practices, you cannot avoid all dependencies, nor would even trying to avoid all possible dependencies be an efficient way to develop.
Example
There are coding practices that can make your code less sensitive to edits to the HTML and I consider those to be desirable practices. For example, consider this HTML snippet:
<div class="header">
<div class="headerBorder">
<div class="actions>
Hide
</div>
<div class="contentContainer">
<div class="content">
... content here
</div>
</div>
</div>
</div>
<div class="header">
... more of these repeated
</div>
And you want to have code that, when you click on the Hide link, it will hide the content.
If you code that like this:
$(".header .actions .hide").click(function() {
$(this).parent().next().children().first().hide();
});
Then, you have embedded in your Javascript some extremely detailed knowledge of the HTML structure in the area of your button and content and pretty much any structural change to that HTML (even just adding one more level of div to help with some layout) will break the Javascript. This is bad.
Instead, you could write this:
$(".header .actions .hide").click(function() {
$(this).closest(".header").find(".content").hide();
});
This depends only upon one HTML structural concept - that the .content that corresponds to the .hide button is somewhere in the common .header parent element. The entire structure within that .header parent can be changed and this code will not break. This is robust code that tries to be as independent of the details of the HTML structure as possible.
Anyway, what I want to learn today is what's the best way to target
the DOM from JS. Is it better to use IDs, class values or, data-*
attributes? How we can prettify a selector with plain English, etc...
It's best to use IDs to target elements for which there is only one unique element in the page.
It's best to use class names to target elements for which there can be more than one element in the page and you can combine that with other parts of a selector if you want to target only a specific item with a class name.
data attributes can be used in selectors, but that isn't really their primary purpose. I can't think of any reason why it would be better to use a data attribute instead of a class name. I use data attributes for storing actual data on an object that will be used by scripts. This tends to allow the code to be more generic and let the content describe itself.
When you talk about classes getting removed to change the state of the element, that is a legitimate use of a class, but it would just be a bad design decision to use the same class for selecting an element as for add/removing state. Use different class names for those two purposes. For example, you could have a class name called "selected" that indicates a selection state, but you would only use that in a selector if you wanted just the selected objects. If you wanted all line items in a table, you wouldn't use ".selected", you'd create a more descriptive class name for that object such as "lineitem". Remember, you can have multiple class names on an object so you can use different class names on the same object for different purposes.
You seem to be searching for some magic bullet here that prevents changes in the HTML from affecting Javascript in any way. That simply does not exist. Selecting a DOM element or finding a DOM element relative to something that was clicked will rely on some inherent knowledge of how the HTML is structured or tagged. What is important is that you minimize that dependence to only what is required and that anyone messing with the HTML has an understanding of how to best change things and not break the Javascript or discusses changes with someone who knows the Javascript. If you're using different skills/people on different portions of the project, they have to coordinate their efforts in order to not break things or be aware of what dependencies there are with the other parts of the system. That's just the way it is. There is no magic answer here that removes all dependencies between HTML and Javascript. Smart designs have smaller and more obvious dependencies. Poor designs have large and often hidden depedencies.
Your question about "plain English" isn't particularly clear to me. It seems obvious to use descriptive ID names, class names or attribute names that make it as obvious to the reader what that particular name is being used for. I'm not sure what you were looking for beyond that.
Do I need somehow "prepare" my HTML before moving on to making my page more sexy with jQuery?
What I mean is there some rule that says that HTML modification with jQuery is easier when HTML has "this" and "that" and "that too"? Some "HTML design patterns" like we have in C++ for example?
My HTML is generated by PHP application from templates and data retrieved from mySql database, and it is styled with CSS so I have ids and classes and almost all "components" on pages are inside divs (with id or class or both) so I presume that it is "jQuery ready" but maybe I should add something more to HTML or think about something?
I mostly have a complete vision what I want to accomplish with jQuery and how page should look like and behave when I finish so it is "only" matter of implementing it but I don't want to get too deep and suddenly discover that if I done something at the beginning my work would be easier and faster.
One advice: generate valid HTML according to whatever DOCTYPE you are using and have fun with jquery. Also avoid mixing markup and javascript: keep them separate and progressively enhance your markup with javascript features.
What you need to do is create a bare HTML page that is usable as-is, meaning, no Javascript required to operate it – that's the ideal anyway, building a web app usually means there's a dependency on Javascript, but you should only use JS when necessary.
Adding Javascript should only enhance your UI while CSS should add the presentation on top of the existing HTML structure. In other words, an HTML page without CSS and Javascript should look and read well.
Is there a way to create your own HTML element? I want to make a specially designed check box.
I imagine such a thing would be done in JavaScript. Something akin to document.createHTMLElement but the ability to design your own element (and tag).
No, there isn't.
The HTML elements are limited to what the browser will handle. That is to say, if you created a custom firefox plugin, and then had it handle your special tag, then you "could" do it, for varying interpretations of "doing it". A list of all elements for a particular version of HTML may be found here: http://www.w3.org/TR/html4/index/elements.html
Probably, however, you don't actually want to. If you want to "combine" several existing elements in such a way as they operate together, then you can do that very JavaScript. For example, if you'd like a checkbox to, when clicked, show a dropdown list somewhere, populated with various things, you may do that.
Perhaps you may like to elaborate on what you actually want to achieve, and we can help further.
Yes, you can create your own tags. You have to create a Schema and import it on your page, and write a JavaScript layer to convert your new tags into existing HTML tags.
An example is fbml (Facebook Markup Language), which includes a schema and a JavaScript layer that Facebook wrote. See this: Open Graph protocol.
Using it you can make a like button really easily:
<fb:like href="http://developers.facebook.com/" width="450" height="80"/>
The easiest way would be probably to write a plugin say in Jquery (or Dojo, MooTools, pick one).
In case of jQuery you can find some plugins here http://plugins.jquery.com/ and use them as a sample.
You need to write own doctype or/and use own namespace to do this.
http://msdn.microsoft.com/en-us/magazine/cc301515.aspx
No, there is not. Moreover it is not allowed in HTML5.
Take a look at Ample SDK JavaScript GUI library that enables any custom elements or event namespaces client-side (this way XUL for example was implemented there) without interferring with the rules of HTML5.
Take a look into for example how XUL scale element implemented: http://github.com/clientside/amplesdk/blob/master/ample/languages/xul/elements/scale.js and its default stylesheet: http://github.com/clientside/amplesdk/blob/master/ample/languages/xul/themes/default/input.css
It's a valid question, but I think the name of the game from the UI side is progressive markup. Build out valid w3 compliant tags and then style them appropriately with javascript (in my case Jquery or Dojo) and CSS. A well-written block of CSS can be reused over and over (my favorite case is Jquery UI with themeroller) and style nearly any element on the page with just a one or two-word addition to the class declaration.
Here's some good Jquery/Javascript/CSS solutions that are relatively simple:
http://www.filamentgroup.com/examples/customInput/
http://aaronweyenberg.com/90/pretty-checkboxes-with-jquery
http://www.protofunc.com/scripts/jquery/checkbox-radiobutton/
Here's the spec for the upcoming (and promising) JqueryUI update for form elements:http://wiki.jqueryui.com/Checkbox
If you needed to validate input, this is an easy way to get inline validation with a single class or id tag: http://www.position-absolute.com/articles/jquery-form-validator-because-form-validation-is-a-mess/
Ok, so my solution isn't a 10 character, one line solution. However, Jquery Code aside, each individual tag wouldn't be much more than:
<input type="checkbox" id="theid">
So, while there would be a medium chunk of Jquery code, the individual elements would be very small, which is important if you're repeating it 250 times (programmatically) as my last project required. It's easy to code, degrades well, validates well, and because progressive markup would be on the user's end, have virtually no cost on the server end.
My current project is in Symfony--not my choice--which uses complex, bulky server-side tags to render form elements, validate, do javascript onclick, style, etc. This seems like what you were asking for at first....and let me tell you, it's CLUNKY. One tag to call a link can be 10 lines of code long! After being forced to do it, I'm not a fan.
Hm. The first thought is that you could create your own element and do a transformation with XSLT to the valid HTML then.
With the emergence of the emerging W3 Web Components standard, specifically the Custom Elements spec, you can now create your own custom HTML elements and register them with the parser with the document.register() DOM method.
X-Tag is a helpful sugar library, developed by Mozilla, that makes it even easier to work with Web Components, have a look: X-Tags.org
I was wondering if it was possible to get Javascript to write some HTML onto the page in a certain DIV.
This is due to the fact, there are certain areas of the site where i don't have access to the markup. But i would like to add a small section there.
For example the container i want to add some html to is
<div id="topics"></div>
Is it possible to get Javascript to do this
<*div id="topics"> <div id="mysection"> </div> <*/div>
Many thanks!
This is fairly simple to do, even using plain JavaScript.
var topicsDiv = document.getElementById("topics");
topicsDiv.innerHTML = '<div id="mysection"> </div>';
If you're going to be doing some serious DOM (Document Object Model, i.e. HTML structure) manipulation, however, then I would recommend you look into using the JQuery library. Yet if the task is limited to your question, then normal JavaScript should be fine, as shown above.
With simple Javascript (without JQuery or something you could do):
HTML:
<div id="topics"></div>
JS:
document.getElementById('topics').innerHTML = '<div id="mysection"></div>';
Using JQuery you would simply do:
$('#topics').append('<div id="mysection"></div>');
Of course. For example, you can do this using Prototype:
$('topics').update('<div id="mysection"></div>');
The syntax is quite similar for jQuery or another frameworks, and as Noldorin noted, you can do also this without any framework.
You are probably looking for the innerHTML property
document.getElementById('topics').innerHTML = 'whatever';
I agree with both Noldorin and Can Berk Güder and others, and I'd like to quote that this is DOM (Document Object Model) and one of the main components of AJAX.
AJAX send a request to a server, and uses techniques such as this to "put it" in the page.
Know that you can do almost anything with javascript; you could just have "<html><body></body></html>" and have javascript do ALL the rest. This is what GWT does, and if you need to HEAVILY modify you page dynamically, you may be interested in it.
HTML (or maybe just XHTML?) is relatively strict when it comes to non-standard attributes on tags. If they aren't part of the spec, then your code is considered non-compliant.
Non-standard attributes can be fairly useful for passing along meta-data to Javascript however. For instance, if a link is suppose to show a popup, you can set the name of the popup in an attribute:
<a href="#null" class="popup" title="See the Popup!"
popup_title="Title for My Popup">click me</a>
Alternatively, you can store the title for the popup in a hidden element, like a span:
<style>
.popup .title { display: none; }
</style>
<a href="#null" title="See the Popup!" class="popup">
click me
<span class="title">Title for My Popup</span>
</a>
I am torn however as to which should be a preferred method. The first method is more concise and, I'm guessing, doesn't screw with search engines and screen readers as much. Conversely, the second option makes storing large amounts of data easier and is thus, more versatile. It is also standards compliant.
I am curious what this communities thoughts are. How do you handle a situation like this? Does the simplicity of the first method outweigh the potential downsides (if there are any)?
I am a big fan of the proposed HTML 5 solution (data- prefixed attributes). Edit: I'd add that there are probably better examples for the use of custom attributes. For instance, data that a custom application will use that have no analogue in standard attributes (eg. customization for event handlers based on something that can't necessarily be expressed in a className or id).
Custom attributes provide a convenient way to carry extra data to the client side. Dojo Toolkit is doing this regularly and it has been pointed (Debunking Dojo Toolkit Myths) out that:
Custom attributes have always been
valid HTML, they just don’t validate
when tested against a DTD. [...] The
HTML specification states that any
attribute not recognized is to be
ignored by the HTML rendering engine
in user agents, and Dojo optionally
takes advantage of this to improve
ease of development.
Another option would be to define something like this in Javascript:
<script type="text/javascript">
var link_titles = {link1: "Title 1", link2: "Title 2"};
</script>
Then you can use this later in your Javascript code, assuming your link has an ID that corresponds to the ID in this hashtable.
It doesn't have the disadvantages of the other two methods: no non-standard attributes nor the ugly hidden span.
The disadvantage is that it might a bit of an overkill for things as simple as your example. But for more complex scenarios, where you have more data to pass, it's a good choice. Especially considering that the data is being passed as JSON, so you can pass complex objects with ease.
Also, you keep data separate from the formatting, which is a good thing for maintainability.
You can even have something like this (which you can't really do with the other methods):
var poi_types = {1: "City", 2: "Restaurant"};
var poi = {1: {lat: X, lng: Y, name: "Beijing", type: 1}, 2: {lat: A, lng: B, name: "Hatsune", type: 2}};
...
<a id="poi-2" href="/poi/2/">Hatsune</a>
And since you most probably use some server-side programming language, this hash table should be trivial to generate dynamically (just serialize it to JSON and spit it in the header section of the page).
Well in this case, the optimal solution is
click
and using title attribute.
Sometimes I break the spec if I really need it. But rarely, and only for good reason.
EDIT: Not sure why the -1, but I was pointing out that sometimes you think you need to break spec, when you don't.
Why not declaring the popup_title attribute in a custom DTD ? This solves the problem with validation. I do this with every non-standard elements, attributes and values and thank this validation shows me only real problems with my code. This makes also any browser errors less possible with such HTML.
You could nest hidden input elements INSIDE the anchor element
<a id="anchor_id">
<input type="hidden" class="articleid" value="5">
Link text here
</a>
Then you can easily pull the data out by
$('#anchor_id .articleid').val()
My solution in the end was to hide additional data in the id tag separated by some sort of delimiter (one underscore is a space, two is the end of that arg), the second arg there is an id:
click
Ugly, and it assumes you're not already using the id tag for something else, but it is compliant across every browser.
My personal feeling in your example is that the span route is more appropriate, as it meets the standards of the XHTML specification. However, i can see an argment for custom attributes, but I think they add a level of confusion that isn't needed.
I've been racking my brain over this as well. I like the readability of non-standard attributes, but I don't like that it will break standard. The hidden span example is compliant, but it is not very readable. What about this:
click
Here the code is very readable, because of JSON's key/value pair notation. You can tell that this is meta data that belongs link just by looking at it. The only flaw I can see beside hijacking the "rel" attribute is that this would get messy for complex objects. I really like that idea of "data-" prefixed attributes mentioned above. Do any current browsers support this?
Here is something else to think about. How much impact does not compliant code have on SEO?