Adapting web pages for foreign language support - html

I have created a set of 13 HTML/CSS/JS templates for CMS integration in the English language.
I need to include support for foreign languages, specifically Russian, Chinese and Arabic. Initial searches online haven't turned up any central resource for guidance on what is required for supporting different languages in HTML.
I understand I'll need to look at things like my font-stacks and character encoding and the Arabic templates will need particular support with my entire layout switching for the right-to-left reading style.
Can anyone point me to some reliable resources for doing this in a standards-compliant way? All templates must meet WCAG 2.0 AA requirements.

Step 1
To start, let’s assume we have the following HTML:
<div>Hello there, how are you?</div>
This DIV layer contains our title. Now, we have decided we want this title to be available in multiple languages. Our first step is adding a class to the div so we can identify it later on:
<div class="title">Hello there, how are you?</div>
Step 2
With that ready, we’re just two steps away. First off, we are going to create an XML file that includes our translations. In this XML file, we can store translations for multiple phrases and we can easily add more languages at a later stage. We shall save this file as languages.xml and save it in the same folder as our HTML file.
<?xml version="1.0" encoding="UTF-8"?>
<translations>
<translation id="title">
<english>Hello there, how are you?</english>
<italian>Ciao, come stai?</italian>
</translation>
</translations>
You will store all phrases you want to translate between the <translations></translations> tags. You will store each phrase in a <translation></translation> tag. In order to identify which phrase is being translated, we need to add the id=”title”. The name should match the name of the CSS class you assigned in the HTML. Finally, we can put the translations inside and surround them by tags defining the language. For instance, we need to put the Italian text in between <italian></italian> tags. Keep in mind that you can easily change the names of these tags – For example, you may choose to use <eng></eng> and <ita></ita> instead.
Step 3
With that complete, you just need to add jQuery to read the XML file and replace the contents of your DIVs based on the language selected. Here you go:
<script src="path/to/jquery.min.js"></script>
<script type="text/javascript" language="javascript">
$(function() {
var language = 'italian';
$.ajax({
url: 'language.xml',
success: function(xml) {
$(xml).find('translation').each(function(){
var id = $(this).attr('id');
var text = $(this).find(language).text();
$("." + id).html(text);
});
}
});
});
</script>
That’s all the code needed – Have a look at it again with comments this time:
// Include jQuery script
<script src="path/to/jquery.min.js"></script>
<script type="text/javascript" language="javascript">
// $(function() { should be used
// each time you use jQuery
$(function() {
// Here we set the language
// we want to display:
var language = 'italian';
// In order to get the translations,
// we must use Ajax to load the XML
// file and replace the contents
// of the DIVs that need translating
$.ajax({
// Here, we specify the file that
// contains our translations
url: 'language.xml',
// The following code is run when
// the file is successfully read
success: function(xml) {
// jQuery will find all <translation>
// tags and loop through each of them
$(xml).find('translation').each(function(){
// We fetch the id we set in the XML
// file and set a var 'id'
var id = $(this).attr('id');
// This is the most important step.
// Based on the language we can set,
// jQuery will search for a matching
// tag and return the text inside it
var text = $(this).find(language).text();
// Last, but not least, we set the
// contents of the DIV with a
// class name matching the id in the
// XML file to the text we just
// fetched
$("." + id).html(text);
});
}
});
});
</script>
And that’s it! Refresh your page and the Italian version should load, replacing the default English one. In the example above, we set the language manually:
var language = 'italian';
We could just as easily set that via PHP:
var language = '<?php echo $sLanguage; ?>';
Or by reading it from the URL – you can use this jQuery Plugin to do that.
Bonus Trick
As you add more languages, you will realize that phrases are longer in certain languages and shorter in others. We might want to have custom CSS for each language. Taking the example above, we would initially have the following:
div.title { font-size:30px; }
What if we wanted the Italian to have a smaller font? Easy! We need to make a slight modification to our jQuery:
$(function() {
var language = 'italian';
$.ajax({
url: 'language.xml',
success: function(xml) {
$(xml).find('translation').each(function(){
var id = $(this).attr('id');
var text = $(this).find(language).text();
$("." + id).html(text);
// Here's the new line we're adding.
// We are assigned the DIV a new class
// which includes the old class name
// plus a "_language" - In this case,
// loading Italian would assign the DIV
// a "title_italian" class
$("." + id).addClass(id + '_' + language);
});
}
});
});
Now that we’ve added that line, we can just add the following CSS:
div.title { font-size:30px; }
div.title_italian { font-size:20px; }
Your Italian text should now be smaller. Note: In order for this to work, you must put the new language CSS definitions underneath the default one. Switching those two lines around will not work.

Sorry for the late answer, but better late than never... :-)
Francois answer is a good solution for a simple and quick solution.
For a more complete and flexible solution (with plural forms handling, for example...), please have a look at: i18next.
They provide:
support for variables
support for nesting
support for context
support for multiple plural forms
gettext support
sprintf supported
detect language
graceful translation lookup
jquery function
get string or object tree
get resourcefiles from server
resource caching in browser
post missing resources to server
highly configurable
custom post processing
translation ui
I'm using i18next solution myself, though I would personally prefer a server-side solution to avoid any additional burden on client side... :-)
N.B. I have no relation at all with i18next.com... :-)

Related

Need to update date code mm/dd/yyyy in in several webpages without using code

I need to get the date from the server in mm/dd/yyyy without any javascript or asp code. I would prefer to do this as either a link that flows in the current document frame and that also injects the mm/dd/yyyy into the current html web page as css or other non code based solution. I don't want to use any extraneous querying languages like xslt, xquery, or plinq either.
example:
<h3>Date:<date format="mm/dd/yyyy" src="currentdate.asp" /></h3>
output:
Date:06/26/2012
No, this is an impossible task.
HTML is a static language. It is impossible to use a static language without any dynamic element (javascript, php, ssi, etc.) and have it change the page.
You will need to find a way to loosen the constrains for your project as it is currently not only impossible but illogical.
EDIT:
I thought of one potential way but it wouldn't be pretty.
You could use an <iframe src="date.asp"> and if the date.asp only returned the date then it would work. This is the only way possible.
as he others say you cannot achieve this without at least a bit of javascript. what you could do is use jquery to select all your date tags and then post an ajax to get the current date in your preferred format.
like so:
<script type="text/javascript">
$(document).ready(function(){
$("date").each(function(index, element) {
var d = $(this);
$.post("ullu.asp", {
ajax: true,
act: "currentdate",
format: d.attr("format")
}, function(data) {
d.after("<span>" + data + "</span>");
});
});
});
</script>
<h3>Date:<date format="%m/%d/%Y" /></h3>
then on ullu.asp:
<%
if request("ajax") = "true" then
dim d : d = DateTime.FormatDate(request("format"), now)
response.write d
end if
%>
DateTime is here a class of mine for formatting dates you could use your own implementation... Furthermore you could add another attribute to your tag like "src" to send your ajax there.
i know you wanted to do this without "using code" but that is not possible. with this solution you only have to add a bit of javascript which handles all your tags...
You can always make it an img, then use an on the fly img generator which generates text as an image from the server. You can use something like csImageFile for generating text in an image on the fly.
http://www.chestysoft.com/imagefile/default.asp
Your image would look like this:
<img src="date.asp" />
Then your date.asp file would be generating a new image (using response.contenttype="image/jpeg" with the current date on each call.
But your date would be displayed as an image, not text.
Or you can use an iFrame like the secretformula's answer, or Ajax/jQuery for this. But if you're not gathering the data from the server, then your date will from the client.

Best practices for Storing JSON in DOM

I want to render some json data using HTML template.
I haven't started implementing anything yet, but I would like to be able to "set" values of data from json to html element which contains template for one record, or to render some collection of items using some argument which is template html for each item, but also to be able to get JSON object back in same format as source JSON which was used to render item (I want my initial JSON to contain some more information about behavior of record row, without the need to make ajax request to check if user can or can't do something with this record, and not all of this info is visible in template).
I know that I could make hidden form with an input element for each property of object to store, and mapper function to/from JSON, but it sounds like overkill to me, and I don't like that, I want some lighter "envelope".
I was wondering is there some JS library that can "serialize" and "deserialize" JSON objects into html so I can store it somewhere in DOM (i.e. in element which contains display for data, but I want to be able to store additional attributes which don't have to be shown as form elements)?
UPDATE As first answer suggested storing JSON in global variable, I also have thought about that, and my "best" mental solution was to make JavaScript module (or jQuery plugin) which would do "mapping" of JSON to html, and if not possible to store values in html then it can store them in internal variable, so when I want to "get" data from html element it can pull it from its local copy. I want to know is there better way for this? If there is some library that stores this info in variable, but does real-time "binding" of that data with html, I would be very happy with that.
UPDATE 2 This is now done using http://knockoutjs.com/, no need to keep json in DOM anymore, knockout does the JSON<=>HTML mapping automatically
Why not store it as nature intended: as a javascript object? The DOM is a horrible place.
That said, jQuery has the data method that allows just this.
So you want to keep a reference to the JSON data that created your DOMFragment from a template?
Let's say you have a template function that takes a template and data and returns a DOM node.
var node = template(tmpl, json);
node.dataset.origJson = json;
node.dataset.templateName = tmpl.name;
You can store the original json on the dataset of a node. You may need a dataset shim though.
There is also no way to "map" JSON to HTML without using a template engine. Even then you would have to store the template name in the json data (as meta data) and that feels ugly to me.
I have done this in the past as well in a couple of different ways.
The $('selector').data idea is probably one of the most useful techniques. I like this way of storing data because I can store the data in a logical, intuitive and orderly fashion.
Let's say you have an ajax call that retrieves 3 articles on page load. The articles may contain data relating to the headline, the date/time, the source etc. Let's further assume you want to show the headlines and when a headline is clicked you want to show the full article and its details.
To illustrate the concept a bit let's say we retrieve json looking something like:
{
articles: [
{
headline: 'headline 1 text',
article: 'article 1 text ...',
source: 'source of the article, where it came from',
date: 'date of the article'
},
{
headline: 'headline 2 text',
article: 'article 2 text ...',
source: 'source of the article, where it came from',
date: 'date of the article'
},
{
headline: 'headline 3 text',
article: 'article 3 text ...',
source: 'source of the article, where it came from',
date: 'date of the article'
}
]
}
From an ajax call like this . . .
$.ajax({
url: "news/getArticles",
data: { count: 3, filter: "popular" },
success: function(data){
// check for successful data call
if(data.success) {
// iterate the retrieved data
for(var i = 0; i < data.articles.length; i++) {
var article = data.articles[i];
// create the headline link with the text on the headline
var $headline = $('<a class="headline">' + article.headline + '</a>');
// assign the data for this article's headline to the `data` property
// of the new headline link
$headline.data.article = article;
// add a click event to the headline link
$headline.click(function() {
var article = $(this).data.article;
// do something with this article data
});
// add the headline to the page
$('#headlines').append($headline);
}
} else {
console.error('getHeadlines failed: ', data);
}
}
});
The idea being we can store associated data to a dom element and access/manipulate/delete that data at a later time when needed. This cuts down on possible additional data calls and effectively caches data to a specific dom element.
anytime after the headline link is added to the document the data can be accessed through a jquery selector. To access the article data for the first headline:
$('#headlines .headline:first()').data.article.headline
$('#headlines .headline:first()').data.article.article
$('#headlines .headline:first()').data.article.source
$('#headlines .headline:first()').data.article.date
Accessing your data through a selector and jquery object is sorta neat.
I don't think there are any libraries that store json in dom.
You could render the html using the data from json and keep a copy of that json variable as a global variable in javascript.

Can I create links with 'target="_blank"' in Markdown?

Is there a way to create a link in Markdown that opens in a new window? If not, what syntax do you recommend to do this? I'll add it to the markdown compiler I use. I think it should be an option.
As far as the Markdown syntax is concerned, if you want to get that detailed, you'll just have to use HTML.
Hello, world!
Most Markdown engines I've seen allow plain old HTML, just for situations like this where a generic text markup system just won't cut it. (The StackOverflow engine, for example.) They then run the entire output through an HTML whitelist filter, regardless, since even a Markdown-only document can easily contain XSS attacks. As such, if you or your users want to create _blank links, then they probably still can.
If that's a feature you're going to be using often, it might make sense to create your own syntax, but it's generally not a vital feature. If I want to launch that link in a new window, I'll ctrl-click it myself, thanks.
Kramdown supports it. It's compatible with standard Markdown syntax, but has many extensions, too. You would use it like this:
[link](url){:target="_blank"}
I don't think there is a markdown feature, although there may be other options available if you want to open links which point outside your own site automatically with JavaScript.
Array.from(javascript.links)
.filter(link => link.hostname != window.location.hostname)
.forEach(link => link.target = '_blank');
jsFiddle.
If you're using jQuery:
$(document.links).filter(function() {
return this.hostname != window.location.hostname;
}).attr('target', '_blank');
jsFiddle.
With Markdown v2.5.2, you can use this:
[link](URL){:target="_blank"}
So, it isn't quite true that you cannot add link attributes to a Markdown URL. To add attributes, check with the underlying markdown parser being used and what their extensions are.
In particular, pandoc has an extension to enable link_attributes, which allow markup in the link. e.g.
[Hello, world!](http://example.com/){target="_blank"}
For those coming from R (e.g. using rmarkdown, bookdown, blogdown and so on), this is the syntax you want.
For those not using R, you may need to enable the extension in the call to pandoc with +link_attributes
Note: This is different than the kramdown parser's support, which is one the accepted answers above. In particular, note that kramdown differs from pandoc since it requires a colon -- : -- at the start of the curly brackets -- {}, e.g.
[link](http://example.com){:hreflang="de"}
In particular:
# Pandoc
{ attribute1="value1" attribute2="value2"}
# Kramdown
{: attribute1="value1" attribute2="value2"}
^
^ Colon
One global solution is to put <base target="_blank">
into your page's <head> element. That effectively adds a default target to every anchor element. I use markdown to create content on my Wordpress-based web site, and my theme customizer will let me inject that code into the top of every page. If your theme doesn't do that, there's a plug-in
Not a direct answer, but may help some people ending up here.
If you are using GatsbyJS there is a plugin that automatically adds target="_blank" to external links in your markdown.
It's called gatsby-remark-external-links and is used like so:
yarn add gatsby-remark-external-links
plugins: [
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [{
resolve: "gatsby-remark-external-links",
options: {
target: "_blank",
rel: "noopener noreferrer"
}
}]
}
},
It also takes care of the rel="noopener noreferrer".
Reference the docs if you need more options.
For ghost markdown use:
[Google](https://google.com" target="_blank)
Found it here:
https://cmatskas.com/open-external-links-in-a-new-window-ghost/
I'm using Grav CMS and this works perfectly:
Body/Content:
Some text[1]
Body/Reference:
[1]: http://somelink.com/?target=_blank
Just make sure that the target attribute is passed first, if there are additional attributes in the link, copy/paste them to the end of the reference URL.
Also work as direct link:
[Go to this page](http://somelink.com/?target=_blank)
You can do this via native javascript code like so:
var pattern = /a href=/g;
var sanitizedMarkDownText = rawMarkDownText.replace(pattern,"a target='_blank' href=");
JSFiddle Code
In my project I'm doing this and it works fine:
[Link](https://example.org/ "title" target="_blank")
Link
But not all parsers let you do that.
There's no easy way to do it, and like #alex has noted you'll need to use JavaScript. His answer is the best solution but in order to optimize it, you might want to filter only to the post-content links.
<script>
var links = document.querySelectorAll( '.post-content a' );
for (var i = 0, length = links.length; i < length; i++) {
if (links[i].hostname != window.location.hostname) {
links[i].target = '_blank';
}
}
</script>
The code is compatible with IE8+ and you can add it to the bottom of your page. Note that you'll need to change the ".post-content a" to the class that you're using for your posts.
As seen here: http://blog.hubii.com/target-_blank-for-links-on-ghost/
If someone is looking for a global rmarkdown (pandoc) solution.
Using Pandoc Lua Filter
You could write your own Pandoc Lua Filter which adds target="_blank" to all links:
Write a Pandoc Lua Filter, name it for example links.lua
function Link(element)
if
string.sub(element.target, 1, 1) ~= "#"
then
element.attributes.target = "_blank"
end
return element
end
Then update your _output.yml
bookdown::gitbook:
pandoc_args:
- --lua-filter=links.lua
Inject <base target="_blank"> in Header
An alternative solution would be to inject <base target="_blank"> in the HTML head section using the includes option:
Create a new HTML file, name it for example links.html
<base target="_blank">
Then update your _output.yml
bookdown::gitbook:
includes:
in_header: links.html
Note: This solution may also open new tabs for hash (#) pointers/URLs. I have not tested this solution with such URLs.
In Laravel I solved it this way:
$post->text= Str::replace('<a ', '<a target="_blank"', $post->text);
Not works for a specific link. Edit all links in the Markdown text. (In my case it's fine)
I ran into this problem when trying to implement markdown using PHP.
Since the user generated links created with markdown need to open in a new tab but site links need to stay in tab I changed markdown to only generate links that open in a new tab. So not all links on the page link out, just the ones that use markdown.
In markdown I changed all the link output to be <a target='_blank' href="..."> which was easy enough using find/replace.
I do not agree that it's a better user experience to stay within one browser tab. If you want people to stay on your site, or come back to finish reading that article, send them off in a new tab.
Building on #davidmorrow's answer, throw this javascript into your site and turn just external links into links with target=_blank:
<script type="text/javascript" charset="utf-8">
// Creating custom :external selector
$.expr[':'].external = function(obj){
return !obj.href.match(/^mailto\:/)
&& (obj.hostname != location.hostname);
};
$(function(){
// Add 'external' CSS class to all external links
$('a:external').addClass('external');
// turn target into target=_blank for elements w external class
$(".external").attr('target','_blank');
})
</script>
You can add any attributes using {[attr]="[prop]"}
For example [Google] (http://www.google.com){target="_blank"}
For completed alex answered (Dec 13 '10)
A more smart injection target could be done with this code :
/*
* For all links in the current page...
*/
$(document.links).filter(function() {
/*
* ...keep them without `target` already setted...
*/
return !this.target;
}).filter(function() {
/*
* ...and keep them are not on current domain...
*/
return this.hostname !== window.location.hostname ||
/*
* ...or are not a web file (.pdf, .jpg, .png, .js, .mp4, etc.).
*/
/\.(?!html?|php3?|aspx?)([a-z]{0,3}|[a-zt]{0,4})$/.test(this.pathname);
/*
* For all link kept, add the `target="_blank"` attribute.
*/
}).attr('target', '_blank');
You could change the regexp exceptions with adding more extension in (?!html?|php3?|aspx?) group construct (understand this regexp here: https://regex101.com/r/sE6gT9/3).
and for a without jQuery version, check code below:
var links = document.links;
for (var i = 0; i < links.length; i++) {
if (!links[i].target) {
if (
links[i].hostname !== window.location.hostname ||
/\.(?!html?)([a-z]{0,3}|[a-zt]{0,4})$/.test(links[i].pathname)
) {
links[i].target = '_blank';
}
}
}
Automated for external links only, using GNU sed & make
If one would like to do this systematically for all external links, CSS is no option. However, one could run the following sed command once the (X)HTML has been created from Markdown:
sed -i 's|href="http|target="_blank" href="http|g' index.html
This can be further automated by adding above sed command to a makefile. For details, see GNU make or see how I have done that on my website.
If you just want to do this in a specific link, just use the inline attribute list syntax as others have answered, or just use HTML.
If you want to do this in all generated <a> tags, depends on your Markdown compiler, maybe you need an extension of it.
I am doing this for my blog these days, which is generated by pelican, which use Python-Markdown. And I found an extension for Python-Markdown Phuker/markdown_link_attr_modifier, it works well. Note that an old extension called newtab seems not work in Python-Markdown 3.x.
For React + Markdown environment:
I created a reusable component:
export type TargetBlankLinkProps = {
label?: string;
href?: string;
};
export const TargetBlankLink = ({
label = "",
href = "",
}: TargetBlankLinkProps) => (
<a href={href} target="__blank">
{label}
</a>
);
And I use it wherever I need a link that open in a new window.
For "markdown-to-jsx" with MUI v5
This seem to work for me:
import Markdown from 'markdown-to-jsx';
...
const MarkdownLink = ({ children, ...props }) => (
<Link {...props}>{children}</Link>
);
...
<Markdown
options={{
forceBlock: true,
overrides: {
a: {
component: MarkdownLink,
props: {
target: '_blank',
},
},
},
}}
>
{description}
</Markdown>
This works for me: [Page Link](your url here "(target|_blank)")

How to self-identify the position of a script's tag in the DOM?

There may be a better way of doing this, but currently I have an nicely encapsulated, JavaScript object which can have some configurable options. I include a chunk of HTML code on a page (via Dreamweaver 'snippets'), and on page load my JS file runs through the DOM and identifies any of those code chunks as a particular functionality, and goes ahead and sets that functionality up.
That's all fine up until I wish to add more than one object on a page, and have them be configurable. The important point here is that you can add as many of these objects onto a page as you like with my current setup - because they're generic at that point, and have no 'id' attribute.
Now I wish to configure these objects, so I thought, "How about an external file containing the config settings, which these objects check for and apply if a config object is found". This works fine too, but the config data feels a bit 'removed' now. I imagine this will be annoying for my other colleagues eventually, it's just another Thing To Remember.
So to my question, I'm happy to insert these code blocks which will still trigger self-instantiating objects on page load - but what I'd like to try is also inserting a script block which contains the config settings. I need a means of that inserted code block knowing that its parent element is the context for configuration.
Example code:
<div class="snippet">
<_contents of this 'snippet'_/>
<script type="text/javascript">
new Snippet().init({
rootElement: REFERENCE_TO_THIS_SCRIPT_TAGS_PARENT_NODE,
configOptionA: true,
configOptionB: false
});
</script>
</div>
Note: The <div class="snippet"> has no 'id' attribute on purpose, because I want to allow for more than one of these to be dropped onto a page.
Other solutions welcome, so long as they adhere to my few restrictions!
My other related question (now answered) addresses this now, essentially I ended up with:
<div class="snippet">
<elements... />
<script type="text/javascript">
var tmpVarName = 'configOb_'+Math.floor(Math.random()*1111111) ;
document[tmpVarName] = {
remainVisible:true,
hoverBehaviour:false
};
</script>
</div>
...and then in a script loaded on every page, which scans for any appropriate elements to instantiate and config:
var snippets = yd.getElementsBy(function(el){
return yd.hasClass(el, "snippet");
},null,document );
for( var i=0; i<snippets.length;i++ )
{
var s = snippets[i] ;
yd.generateId(s, '_snippet_'+i );
var tag = yd.getElementBy(function(el){
return true;
},'script',s );
var ob = new Snippet();
ob.setId( s.id );
ob.init( eval( tag.innerHTML ) );
}
For a more complete context of the above code;
yd = YAHOO.util.Dom
Snippet.init() and Snippet.setId() are exposed methods on a Module object called Snippet()
Now that my inserted 'chunks' of content have no id attribute, and dynamically evaluated, contextual config objects - I am free to add as many variants as I like. My only real concern is performance if a whole bunch of these Snippet() objects are added to my page (not likely).

Naming "class" and "id" HTML attributes - dashes vs. underlines [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
<div id="example-value"> or <div id="example_value">?
This site and Twitter use the first style. Facebook and Vimeo - the second.
Which one do you use and why?
Use Hyphens to ensure isolation between your HTML and JavaScript.
Why? see below.
Hyphens are valid to use in CSS and HTML but not for JavaScript Objects.
A lot of browsers register HTML Ids as global objects on the window/document object, in big projects, this can become a real pain.
For this reason, I use names with Hyphens this way the HTML ids will never conflict with my JavaScript.
Consider the following:
message.js
message = function(containerObject){
this.htmlObject = containerObject;
};
message.prototype.write = function(text){
this.htmlObject.innerHTML+=text;
};
html
<body>
<span id='message'></span>
</body>
<script>
var objectContainer = {};
if(typeof message == 'undefined'){
var asyncScript = document.createElement('script');
asyncScript.onload = function(){
objectContainer.messageClass = new message(document.getElementById('message'));
objectContainer.messageClass.write('loaded');
}
asyncScript.src = 'message.js';
document.appendChild(asyncScript);
}else{
objectContainer.messageClass = new message(document.getElementById('message'));
objectContainer.messageClass.write('loaded');
}
</script>
If the browser registers HTML ids as global objects the above will fail because the message is not 'undefined' and it will try to create an instance of the HTML object. By making sure an HTML id has a hyphen in the name prevents conflicts like the one below:
message.js
message = function(containerObject){
this.htmlObject = containerObject;
};
message.prototype.write = function(text){
this.htmlObject.innerHTML+=text;
};
html
<body>
<span id='message-text'></span>
</body>
<script>
var objectContainer = {};
if(typeof message == 'undefined'){
var asyncScript = document.createElement('script');
asyncScript.onload = function(){
objectContainer.messageClass = new message(document.getElementById('message-text'));
objectContainer.messageClass.write('loaded');
}
asyncScript.src = 'message.js';
document.appendChild(asyncScript);
}else{
objectContainer.messageClass = new message(document.getElementById('message-text'));
objectContainer.messageClass.write('loaded');
}
</script>
Of course, you could use messageText or message_text but this doesn't solve the problem and you could run into the same issue later where you would accidentally access an HTML Object instead of a JavaScript one
One remark, you can still access the HTML objects through the (for example) window object by using window['message-text'];
I would recommend the Google HTML/CSS Style Guide
It specifically states:
Separate words in ID and class names by a hyphen. Do not concatenate words and abbreviations in selectors by any characters (including none at all) other than hyphens, in order to improve understanding and scannability.
/* Not recommended: does not separate the words “demo” and “image” */
.demoimage {}
/* Not recommended: uses underscore instead of hyphen */
.error_status {}
/* Recommended */
#video-id {}
.ads-sample {}
It really comes down to preference, but what will sway you in a particular direction might be the editor you code with. For instance, the auto-complete feature of TextMate stops at a hyphen, but sees words separated by an underscore as a single word. So class names and ids with the_post work better than the-post when using its auto-complete feature (Esc).
I believe this is entirely up to the programmer. You could use camelCase too if you wanted (but I think that would look awkward.)
I personally prefer the hyphen, because it is quicker to type on my keyboard. So I would say that you should go with what you are most comfortable with, since both your examples are widely used.
Either example is perfectly valid, you can even throw into the mix ":" or "." as separators according to the w3c spec. I personally use "_" if it is a two word name just because of its similarity to space.
I use the first one (one-two) because its more readable. For images though I prefer the underscore (btn_more.png). Camel Case (oneTwo) is another option.
Actually some external frameworks (javascript, php) have difficulties (bugs?) with using the hypen in id names. I use underscore (so does 960grid) and all works great.
I would suggest underscore mainly for the reason of a javascript side-effect I'm encountering.
If you were to type the code below into your location bar, you would get an error: 'example-value' is undefined. If the div were named with underscores, it would work.
javascript:alert(example-value.currentStyle.hasLayout);