I have a script like this:
example.js:
function ex1(){document.write('example1');}
function ex2(){document.write('example2');}
ex1();
ex2();
I want to use ex1() and ex2() from example.js in different places of my html page, and styling them differently.
So how can I call these ex1() and ex2 separately in my html. Is it possible? If possible, how?
Thanks,
If you have the file referenced from your html, you can call these functions without any problem.
What do you mean by "styling" them though?
And what is the difference between the functions?
EDIT OP wants different styles for output in each function:
function ex1(){document.write('<p class="classone">example1</p>');}<br>
function ex2(){document.write('<p class="classtwo">example1</p>'');}
After that, modify your CSS like this:
.classone{
// styles for the first
}
.classtwo{
// styles for the second
}
As a sort of quick explanation, document.write replaces the content of the page with whatever is inside the parantheses "()":
eg. document.write("hello world"); // Replaces everything with "hello world"
This is because the document part of the code refers to all the content in the body of the page (essentially everything that you see).
To put text in only a specific part of the page, you'll have to reference that item/element in which you want to place the text first. You can do this in a number of ways, such as referencing by element (as in #metal_fan's example), by class, element-type, etc. You can also use frameworks such as jQuery which specialize in referencing elements.
jQuery version of #metal_fan's solution:
eg. jQuery("#myId").html("hello world"); // Replaces content of #myId element with "hello world"
As #Kenneth implied (albeit a bit harshly), to use this well, you may need to increase your understanding of javascript and HTML. Might I suggest signing up for codingacademy.com turorials? They are pretty comprehensive, you gain points, and its free.
Good luck!
Related
Pretty simple question that I couldn't find an answer to, maybe because it's a non-issue, but I'm wondering if there is a difference between creating an HTML object using Javascript or using a string to build an element. Like, is it a better practice to declare any HTML elements in JS as JS objects or as strings and let the browser/library/etc parse them? For example:
jQuery('<div />', {'class': 'example'});
vs
jQuery('<div class="example></div>');
(Just using jQuery as an example, but same question applies for vanilla JS as well.)
It seems like a non-issue to me but I'm no JS expert, and I want to make sure I'm doing it right. Thanks in advance!
They're both "correct". And both are useful at different times for different purposes.
For instance, in terms of page-speed, these days it's faster to just do something like:
document.body.innerHTML = "<header>....big string o' html text</footer>";
The browser will spit it out in an instant.
As a matter of safety, when dealing with user-input, it's safer to build elements, attach them to a documentFragment and then append them to the DOM (or replace a DOM node with your new version, or whatever).
Consider:
var userPost = "My name is Bob.<script src=\"//bad-place.com/awful-things.js\"></script>",
paragraph = "<p>" + userPost + "</p>";
commentList.innerHTML += paragraph;
Versus:
var userPost = "My name is Bob.<script src=\"//bad-place.com/awful-things.js\"></script>",
paragraph = document.createElement("p");
paragraph.appendChild( document.createTextNode(userPost) );
commentList.appendChild(paragraph);
One does bad things and one doesn't.
Of course, you don't have to create textNodes, you could use innerText or textContent or whatever (the browser will create the text node on its own).
But it's always important to consider what you're sharing and how.
If it's coming from anywhere other than a place you trust (which should be approximately nowhere, unless you're serving static pages, in which case, why are you building html?), then you should keep injection in mind -- only the things you WANT to be injected should be.
Either can be preferable depending on your particular scenario—ie, if everything is hard-coded, option 2 is probably better, as #camus said.
One limitation with the first option though, is that this
$("<div data-foo='X' />", { 'class': 'example' });
will not work. That overload expects a naked tag as the first parameter with no attributes at all.
This was reported here
1/ is better if your attribubes depends on variables set before calling the $ function , dont have to concatenate strings and variables. Aside from that fact ,since you can do both , and it's just some js code somebody else wrote , not a C++ DOM API hardcoded in the browser...
Hi this may be a silly question, but I can't find the answer anywhere.
I'm writing a chrome extension, all I need is to read in the html of the current page so I can extract some data from it.
here's what I have so far:
<script>
window.addEventListener("load", windowLoaded, false);
function windowLoaded() {
alert(document.innerHTML)
});
}
</script>
Can anybody tell me what I'm doing wrong?
thanks,
function windowLoaded() {
alert('<html>' + document.documentElement.innerHTML + '</html>');
}
addEventListener("load", windowLoaded, false);
Notice how windowLoaded is created before it is used, not after, which won't work.
Also notice how I am getting the innerHTML of document.documentElement, which is the html tag, then adding the html source tags around it.
I'm writing a chrome extension, all I need is to read in the html of
the current page so I can extract some data from it.
I think an important answer here is not the correct code to use to alert the innerHTML but how to get the data you need from what's already been rendered.
As pimvdb pointed out, your code isn't working because of a typo and needing document.documentElement.innerHTML, something you can diagnose in the Chrome console (Ctrl+Shift+I). But that's secondary to why you'd want the inner HTML in the first place. Whether you're looking for a certain node, specific text, how many <div> elements exist, the value of an ID, etc., I'd heavily recommend the use of a library like jQuery (vanilla JS works, but it can be verbose and unwieldy). Instead of reading in all the HTML and parsing it with string functions or regex, you probably want to take advantage of all the DOM parsing functionality already available to you.
In other words, something like this:
$("#some_id").val(); // jQuery
document.getElementById("some_id").value; // vanilla JS
is probably way safer, easier and more readable than something eminently breakable like this (probably a bit off here, but just to make a point):
innerHTML.match(/<[^>]+id="some_id"[^>]+value="(.*?)"[^>]*?>/i)[1];
Use document.documentElement.outerHTML. (Note that this is not supported in Firefox; irrelevant in your case.) However, this is still not perfect as it doesn't return nodes outside the root element (!doctype and possibly some comments or processing instructions). The document.innerHTML property is, AFAIK, specified in HTML5 specification, but currently not supported in any browser.
Just FYI, navigating to view-source:www.example.com also displays the entire markup (Chrome & Firefox). But I don't know whether you can work with it somehow.
window.addEventListener("load", windowLoaded, false);
function windowLoaded() {
alert(document.documentElement.innerHTML);
}
You had a } with no purpose, and the }); should just be }. These are syntax errors.
Also, it's document.documentElement.innerHTML, since it's not a property of document.
It is very often I come across a situation in which I want to modify, or even insert whole blocks of HTML into a page using JavaScript. Usually it also involves changing several parts of the HTML dynamically depending on certain parameters.
However, it can make for messy/unreadable code, and it just doesn't seem right to have these little snippets of HTML in my JavaScript code, dammit.
So, what are some of your techniques to avoid mixing HTML and JavaScript?
The Dojo toolkit has a quite useful system to deal with HTML fragments/templates. Let's say the HTML snippet mycode/mysnippet.tpl.html is something like the following
<div>
<span dojoAttachPoint="foo"></span>
</div>
Notice the dojoAttachPoint attribute. You can then make a widget mycode/mysnippet.js using the HTML snippet as its template:
dojo.declare("mycode.mysnippet", [dijit._Widget, dijit._Templated], {
templateString: dojo.cache("mycode", "mysnippet.tpl.html"),
construct: function(bar){
this.bar = bar;
},
buildRendering: function() {
this.inherited(arguments);
this.foo.innerHTML = this.bar;
}
});
The HTML elements given attach point attributes will become class members in the widget code. You can then use the templated widget like so:
new mycode.mysnippet("A cup of tea would restore my normality.").placeAt(someOtherDomElement);
A nice feature is that if you use dojo.cache and Dojo's build system, it will insert the HTML template text into the javascript code, so that the client doesn't have to make a separate request.
This may of course be way too bloated for your use case, but I find it quite useful - and since you asked for techniques, there's mine. Sitepoint has a nice article on it too.
There are many possible techniques. Perhaps the most obvious is to have all elements on the page but have them hidden - then your JS can simply unhide them/show them as required. This may not be possible though for certain situations. What if you need to add a number (unspecified) of duplicate elements (or groups of elements)? Then perhaps have the elements in question hidden and using something like jQuery's clone function insert them as required into the DOM.
Alternatively if you really have to build HTML on the fly then definitely make your own class to handle it so you don't have snippets scattered through your code. You could employ jQuery literal creators to help do this.
I'm not sure if it qualifies as a "technique", but I generally tend to avoid constructing blocks of HTML in JavaScript by simply loading the relevant blocks from the back-end via AJAX and using JavaScript to swap them in and out/place them as required. (i.e.: None of the low-level text shuffling is done in JavaScript - just the DOM manipulation.)
Whilst you of course need to allow for this during the design of the back-end architecture, I can't help but think to leads to a much cleaner set up.
Sometimes I utilise a custom method to return a node structure based on provided JSON argument(s), and add that return value to the DOM as required. It ain't accessible once JS is unavailable like some backend solutions could be.
After reading some of the responses I managed to come up with my own solution using Python/Django and jQuery.
I have the HTML snippet as a Django template:
<div class="marker_info">
<p> _info_ </p>
more info...
</div>
In the view, I use the Django method render_to_string to load the templates as strings stored in a dictionary:
snippets = { 'marker_info': render_to_string('templates/marker_info_snippet.html')}
The good part about this is I can still use the template tags, for example, the url function. I use simplejson to dump it as JSON and pass it into the full template. I still wanted to dynamically replace strings in the JavaScript code, so I wrote a function to replace words surrounded by underscores with my own variables:
function render_snippet(snippet, dict) {
for (var key in dict)
{
var regex = new RegExp('_' + key + '_', 'gi');
snippet = snippet.replace(regex, dict[key]);
}
return snippet;
}
Is there an easy way, for example, to drop an XML name space, but keep the tag as is with jQuery or JavaScript? For example:
<html:a href="#an-example" title="Go to the example">Just an Example</html:a>
And change it to:
Just an Example
On the fly with jQuery or JavaScript and not knowing the elements and or attributes inside?
If there is no <script> tag in the code to be replaced you can try (demo):
container.innerHTML = container.innerHTML
.replace(/<(\/?)([^:>\s]*:)?([^>]+)>/g, "<$1$3>")
This isn't really an answer, but you'd be better off handling this server-side. JavaScript comes into the picture a bit too late for this kind of task... events may have already been attached to the existing nodes and you'd be processing each element twice.
What is the purpose of the namespace?
If these are static html files and the namespace serves no purpose I would strip all the namespaces with a regex.
If they're not static and the namespace has a purpose when served as xml, you could do some server-side detection to serve with the right doctype and the namespace (when appropriate).
It's easy when you know how ... just use \\ to escape the colon so it's not parsed as an action delimiter by the jquery parsing engine.
$('html\\:a').each( function(){
var temp = $(this).html();
$(this).replaceWith("<a>"+temp+"</a>");
});
This should iterate between each of those elements and replace them with normal tags. Since these are being served up to an ajax callback function, otherwise I don't see why you'd want to do it on the fly ... then the top line would change to:
$.post('...',{}, function(dat){
$(dat).find('html\\:a').each( blah blah ....
.
.
});
NB, i'm one of those terrible people who only really tests things in FF ...
For example in javascript code running on the page we have something like:
var data = '<html>\n <body>\n I want this text ...\n </body>\n</html>';
I'd like to use and at least know if its possible to get the text in the body of that html string without throwing the whole html string into the DOM and selecting from there.
First, it's a string:
var arbitrary = '<html><body>\nSomething<p>This</p>...</body></html>';
Now jQuery turns it into an unattached DOM fragment, applying its internal .clean() method to strip away things like the extra <html>, <body>, etc.
var $frag = $( arbitrary );
You can manipulate this with jQuery functions, even if it's still a fragment:
alert( $frag.filter('p').get() ); // says "<p>This</p>"
Or of course just get the text content as in your question:
alert( $frag.text() ); // includes "This" in my contrived example
// along with line breaks and other text, etc
You can also later attach the fragment to the DOM:
$('div#something_real').append( $frag );
Where possible, it's often a good strategy to do complicated manipulation on fragments while they're unattached, and then slip them into the "real" page when you're done.
The correct answer to this question, in this exact phrasing, is NO.
If you write something like var a = $("<div>test</div>"), jQuery will add that div to the DOM, and then construct a jQuery object around it.
If you want to do without bothering the DOM, you will have to parse it yourself. Regular expressions are your friend.
It would be easiest, I think, to put that into the DOM and get it from there, then remove it from the DOM again.
Jquery itself is full of tricks like this. It's adding all sorts off stuff into the DOM all the time, including when you build something using $('<p>some html</p>'). So if you went down that road you'd still effectively be placing stuff into the DOM then removing it again, temporarily, except that it'd be Jquery doing it.
John Resig (jQuery author) created a pure JS HTML parser that you might find useful. An example from that page:
var dom = HTMLtoDOM("<p>Data: <input disabled>");
dom.getElementsByTagName("body").length == 1
dom.getElementsByTagName("p").length == 1
Buuuut... This question contains a constraint that I think you need to be more critical of. Rather than working around a hard-coded HTML string in a JS variable, can you not reconsider why it's that way in the first place? WHAT is that hard-coded string used for?
If it's just sitting there in the script, re-write it as a proper object.
If it's the response from an AJAX call, there is a perfectly good jQuery AJAX API already there. (Added: although jQuery just returns it as a string without any ability to parse it, so I guess you're back to square one there.)
Before throwing it in the DOM that is just a plain string.
You can sure use REGEX.