popluating multiple id tags - javascript

How can i populate multiple id tags simultaneously.
On my page i have id tags starting with "total_" phrase, like total_1, total_2 etc., is there a way by which i can populate each of them on a single click in javascript.
Should i use regex or parser.
Any help will be highly appreciated.
Thank you.

for(var i=1; true; i++){
var elm = document.getElementById("total_"+i);
if(elm == undefined){
break;
}
elm.innerHTML = "Some text here";
}
Using jQuery you can do the following:
$("div[id^='total_']").html("Some text Here");

If you know how many there are, you can simply loop through the numbers:
for (var i=1; i<=10; i++) {
document.getElementById('total_'+i).innerHTML = 'text';
}
If you are using jQuery, you can loop through all elements of a specific type, and look for the id. It's less efficient, but more flexible. It will work even if the numbers are not contiguous:
$('div').filter(this.id && this.id.substr(0,6) == 'total_').html('text');
(You can of course loop through elements without a library like jQuery, but then it's a bit more code...)

Related

Removing duplicate page elements - Javascript

I am looking to get a list of elements with a certain tag and if there is more than one loop through and remove the additional elements.
Currently I do:
if (document.getElementsByName("description")[0]) {
document.getElementsByName("description")[0].setAttribute("content", "My Description");
} else {
var meta = document.createElement('meta');
meta.name = "description";
meta.content = "My Description";
document.getElementsByTagName('head')[0].appendChild(meta);
}
But I want to remove anything that is after the first element? How would I do that?
you can do this:
[...document.getElementsByTagName('span')].slice(1).forEach(e=>e.parentNode.removeChild(e));
[...document.getElementsByTagName('div')].slice(1).forEach(e=>e.parentNode.removeChild(e));
First select all elements with the specific tag name. Transform it to an array (in this case with spread operator, you can also use [].slice.call(...). After that you can call slice on that array of elements and remove the first one out of this set. Loop through the elements and remove them. That's all :)
EDIT Solution for beginners:
var elements = document.getElementsByTagName('span');
for(var i=elements.length-1;i>0;i--)
elements[i].parentNode.removeChild(elements[i]);
If you want cut anything after description[0] in header, you can use that
'document.getElementsByTagName["head"].innerHTML = "";'
If you only want cut any description tags, use
var tags = document.getElementsByTagName('description');
for(i=0; i<tags.length; i++){
tags[i].remove();
}

why innerHTML does not return true when compared with same string value?

I have two tables on my html page with exact same data but there may be few difference which need to be highlighted.
I and using the below Javascript but seems innerHTML does not work as expected-
function CompareTables()
{
var table1 = document.getElementById("table1")
var table2 = document.getElementById("table2")
for(var i=1; i < table1.rows.length; i++)
{
for(var j=1; j < table2.rows.length; j++){
var tab1Val = table1.rows[i].cells[0].innerHTML;
var tab2Val = table2.rows[j].cells[0].innerHTML;
alert(tab1Val.toUpperCase()+"----"+tab2Val.toUpperCase());
var changes =RowExists(table2,tab1Val);
if(!changes[0])
{
table1.rows[i].style.backgroundColor = "red";
instHasChange = true;
}
}
function RowExists(table,columnValue)
{
var hasColumnOrChange = new Array(2);
hasColumnOrChange[0] = false;
for(var i=1; i < table.rows.length; i++)
{
if(table.rows[i].cells[0].innerHTML == columnValue) /*** why these two does not match**/
{
hasColumnOrChange[0] = true;
}
return hasColumnOrChange;
}
}
Please suggest what wrong here.
(table.rows[i].cells[0].innerHTML == columnValue) never returns true even if all values same.
most browsers have bugs with innerHTML and it is not a recommended property to use. different browsers will do different things, usually messing with whitespace, adding/removing quotes, and/or changing the order of attributes.
long story short, never rely on innerHTML.
In it's place, I would recommend using some of the DOM traversal functions, such as .firstChild and .nodeValue. Notice that these are sensitive of white space, and will have to be tweaked if you have anything else in your TD than just text.
http://jsfiddle.net/tdN5L/
if (table.rows[i].cells[0].firstChild.nodeValue === columnValue)
Another option, as pointed out by Micah's solution, is using a library such as jQuery, which will let you ignore most of these browser issues and DOM manipulation pain. I would not recommend bringing in the overhead of jQuery just for this issue, though.
related:
Firefox innerHTML Bug?
innerHTML bug IE8
innerHTML removes attribute quotes in Internet Explorer
Try and use Jquery's method .text
Depending on the browser(Firefox and Chrome's) innerHTML does not work
JQuery takes care of that issue for you.

Selecting multiple, but not all HTML classes

So lets say I want to hide a div or span with CSS of a particular class.
Is there anyway to do so for the first X number of instances, or better yet, do it for all except for the last one? I imagine this would require javascript.
pseudocode I am thinking would look like this
if divname.class = "XYZ" {
select all instances -1
execute code that inserts random programmatic id into each class
execute code that hides all ids except the last one
}
Am I on the right track? Or is there any easier/better way?
If you can use jQuery and its nice pseudo-selectors, you could do something like
$('.question-summary:not(:last)')
You can test on the SO homepage.
You could do something like this,
var class_div = document.getElementsByClassName("class_name");
var i =0;
for(i=0;i<class_div.length-1;i++){
//do whatever you want with class_div[n-1] elements.
}
I am not sure how you do this with jquery but this is one possible solution for javascript.
If you were using jQuery...
$('.class_name').hide().last().show();
Here ya go - http://jsfiddle.net/uUK6G/
Set all your divs to the same class. Then use jQuery to filter out the last one.
$('.myDiv').filter(':not(:last)').hide();​
You can use the :last-child selector in CSS to do this.
http://www.w3schools.com/cssref/sel_last-child.asp
Is there anyway to do so for the first X number of instances, or
better yet, do it for all except for the last one? I imagine this
would require javascript.
You can try:
var elms = document.getElementsByClassName('XYZ'), total = elms.length;
for (var i = 0; i < total; i++){
elms[i].style.display = 'none';
}
In above loop, i will contain index of each element, you can put condition or rather range to specify which ones to delete. For example, if you wanted to hide all except for last one, you would modify it like:
for (var i = 0; i < total - 1; i++){
elms[i].style.display = 'none';
}

how to using "For" instead of "each" function in jquery

Today i'm very stack with a Work and jQ. I was get a morning for it but i can't resolve it :(.
My Work here:
<div class="container">
<p class="test">a</p>
<div>
<p class="test">a</p>
</div>
</div>
In normal, i can using jQ with each function for select all <p class="test">a</p> EX:
$(".test").each(function() {
$(this).text('a');
});
But i hear everyone talk that, for function get a less timeload than each function. Now i want using for instead of each.. but i don't know how to write code jQ in this case.
Somebody can help me!. thankyou!
I wouldn't worry about it unless you were iterating through hundreds of them.
for loop is usually used with normal DOM (aka without jQuery) traversing, like...
var elements = document.getElementById('something').getElementsByTagName('a');
var elementsLength = elements.length;
for (var i = 0; i < elementsLength; i++) {
elements[i].style.color = 'red';
}
Caching of elementsLength is a good idea so it is not calculated every iteration. Thanks to CMS for this suggestion in the comments.
Just adapt that for your jQuery object if you wanted to do it with jQuery.
Replace elements variable with your jQuery collection, like $('#something a'). I think you may need to rewrap the object if you need to do any more jQuery stuff with it.
One thing to watch out for is that using an ordinal accessor on the result of a jQuery selection will return a native DomElement. If you want to use jQuery methods on them, you have to re-wrap them:
var testElements = $('.test');
for (var i = 0; i < testElements.length; i++) {
// Using $() to re-wrap the element.
$(testElements[i]).text('a');
}
I'd second what others have said though. Unless you're dealing with many elements, this is premature optimization. Re-wrapping the elements to use the .text() method may even bring it back to no gain at all.
have you tried the obvious solution?
var nodes = $(".test");
for(var i = 0; i < nodes.length; i++)
{
var node = nodes[i];
}
This article shows that each() has no significant performance penalty until you get into the hundreds of thousands of looped-over items.
Another alternative:
for (var i = 0; i < $('.test').length; i++){
var element = $('.test').eq(i);
}

How can I use jQuery to style /parts/ of all instances of a specific word?

Unusual situation. I have a client, let's call them "BuyNow." They would like for every instance of their name throughout the copy of their site to be stylized like "BuyNow," where the second half of their name is in bold.
I'd really hate to spend a day adding <strong> tags to all the copy. Is there a good way to do this using jQuery?
I've seen the highlight plugin for jQuery and it's very close, but I need to bold just the second half of that word.
To do it reliably you'd have to iterate over each element in the document looking for text nodes, and searching for text in those. (This is what the plugin noted in the question does.)
Here's a plain JavaScript/DOM one that allows a RegExp pattern to match. jQuery doesn't really give you much help here since selectors can only select elements, and the ‘:contains’ selector is recursive so not too useful to us.
// Find text in descendents of an element, in reverse document order
// pattern must be a regexp with global flag
//
function findText(element, pattern, callback) {
for (var childi= element.childNodes.length; childi-->0;) {
var child= element.childNodes[childi];
if (child.nodeType==1) {
findText(child, pattern, callback);
} else if (child.nodeType==3) {
var matches= [];
var match;
while (match= pattern.exec(child.data))
matches.push(match);
for (var i= matches.length; i-->0;)
callback.call(window, child, matches[i]);
}
}
}
findText(document.body, /\bBuyNow\b/g, function(node, match) {
var span= document.createElement('span');
span.className= 'highlight';
node.splitText(match.index+6);
span.appendChild(node.splitText(match.index+3));
node.parentNode.insertBefore(span, node.nextSibling);
});
Regular Expressions and replace() spring to mind. Something like
var text = $([selector]).html();
text = text.replace(/Now/g,'<strong>Now<\strong>');
$([selector]).html(text);
A word of caution in using html() to do this. Firstly, there is the potential to replace matched strings in href attributes of <a> elements and other attributes that may cause the page to then incorrectly function. It might be possible to write a better regular expression to overcome some of the potential problems, but performance may suffer (I'm no regular expression guru). Secondly, using html() to replace content will cause non-serializable data such as event handlers bound to elements markup that is replaced, form data, etc. to be lost. Writing a function to target only text nodes may be the better/safer option, it just depends on how complex the pages are.
If you have access to the HMTL files, it would probably be better to do a find and replace on the words they want to change the appearance of in the files if the content is static. NotePad++'s Find in Files option is performant for this job in most cases.
Going with SingleShot's suggestion and using a <span> with a CSS class will afford more flexibility than using a <strong> element.
I wrote a little plugin to do just that. Take a look at my answer to a similar question.
Instead of downloading the plugin suggested in the accepted answer, I strongly recommend that you use the plugin I've written--it's a lot faster.
var Run=Run || {};
Run.makestrong= function(hoo, Rx){
if(hoo.data){
var X= document.createElement('strong');
X.style.color= 'red'; // testing only, easier to spot changes
var pa= hoo.parentNode;
var res, el, tem;
var str= hoo.data;
while(str && (res= Rx.exec(str))!= null){
var tem= res[1];
el= X.cloneNode(true);
el.appendChild(document.createTextNode(tem));
hoo.replaceData(res.index, tem.length,'');
hoo= hoo.splitText(res.index);
str= hoo.data;
if(str) pa.insertBefore(el, hoo);
else{
pa.appendChild(el);
return;
}
}
}
}
Run.godeep= function(hoo, fun, arg){
var A= [];
if(hoo){
hoo= hoo.firstChild;
while(hoo!= null){
if(hoo.nodeType== 3){
if(hoo.data) A[A.length]= fun(hoo, arg);
}
else A= A.concat(arguments.callee(hoo, fun, arg));
hoo= hoo.nextSibling;
}
}
return A;
}
//test
**Run.godeep(document.body, Run.makestrong,/([Ee]+)/g);**
This is not a jQuery script but pure javaScript, i believe it can be altered a little.
Link.

Categories