Prepend some innerHTML to a div in Native Javascript - javascript

Please bear with me on this question; I have only recently started coding in Javascript and for this reason I would like a strong foundation before breaking into jQuery.
I have the following Javascript code:
var app = {
text: document.getElementById('text'),
output: document.getElementById('output'),
createDiv: document.createElement('div')
};
function postData(){
app.output[0].appendChild(app.createDiv.firstChild);
app.createDiv.classname = 'text';
document.getElementsByClassName('username').innerHTML += app.text.value;
}
onClick I want the value of app.text to print (using innerHTML) ABOVE the output div. Any ideas or questions? Sorry if I am being vague or not making sense, I have been staring at this for 4 hours now and am probably just burned out!

You'll have to create a text node and insert it before each element in the NodeList returned by document.getElementsByClassName:
var node = document.createTextNode(app.text.value);
var elements = document.getElementsByClassName('username');
for (var i = 0; i < elements.length; i++) {
var elem = elements[i];
elem.parentNode.insertBefore(node.cloneNode(), elem)
}
And just to tempt you with the jQuery version:
$('.username').before(app.text.value);

I'm not sure what you're asking, but I see the following problems with your code:
app.output[0]: there should be no [0], app.output is already an element (you got it by id). So use app.output.appendChild(app.createDiv.firstChild);. Still, this makes no sense; as Barmar said, you just created that div, so it doesn't have any children at that point.
app.createDiv.classname: should be className
document.getElementsByClassName('username').innerHTML: this returns multiple elements, maybe you want document.getElementsByClassName('username')[0].innerHTML?

Related

Onclick doesn't work in userscript [duplicate]

I am trying to run a function onclick of any button with class="stopMusic". I'm getting an error in Firebug
document.getElementByClass is not a function
Here is my code:
var stopMusicExt = document.getElementByClass("stopButton");
stopButton.onclick = function() {
var ta = document.getElementByClass("stopButton");
document['player'].stopMusicExt(ta.value);
ta.value = "";
};
You probably meant document.getElementsByClassName() (and then grabbing the first item off the resulting node list):
var stopMusicExt = document.getElementsByClassName("stopButton")[0];
stopButton.onclick = function() {
var ta = document.getElementsByClassName("stopButton")[0];
document['player'].stopMusicExt(ta.value);
ta.value = "";
};
You may still get the error
document.getElementsByClassName is not a function
in older browsers, though, in which case you can provide a fallback implementation if you need to support those older browsers.
Before jumping into any further error checking please first check whether its
document.getElementsByClassName() itself.
double check its getElements and not getElement
As others have said, you're not using the right function name and it doesn't exist univerally in all browsers.
If you need to do cross-browser fetching of anything other than an element with an id with document.getElementById(), then I would strongly suggest you get a library that supports CSS3 selectors across all browsers. It will save you a massive amount of development time, testing and bug fixing. The easiest thing to do is to just use jQuery because it's so widely available, has excellent documentation, has free CDN access and has an excellent community of people behind it to answer questions. If that seems like more than you need, then you can get Sizzle which is just a selector library (it's actually the selector engine inside of jQuery and others). I've used it by itself in other projects and it's easy, productive and small.
If you want to select multiple nodes at once, you can do that many different ways. If you give them all the same class, you can do that with:
var list = document.getElementsByClassName("myButton");
for (var i = 0; i < list.length; i++) {
// list[i] is a node with the desired class name
}
and it will return a list of nodes that have that class name.
In Sizzle, it would be this:
var list = Sizzle(".myButton");
for (var i = 0; i < list.length; i++) {
// list[i] is a node with the desired class name
}
In jQuery, it would be this:
$(".myButton").each(function(index, element) {
// element is a node with the desired class name
});
In both Sizzle and jQuery, you can put multiple class names into the selector like this and use much more complicated and powerful selectors:
$(".myButton, .myInput, .homepage.gallery, #submitButton").each(function(index, element) {
// element is a node that matches the selector
});
It should be getElementsByClassName, and not getElementByClass. See this - https://developer.mozilla.org/en/DOM/document.getElementsByClassName.
Note that some browsers/versions may not support this.
My solutions is:
Change:
document.getElementsByClassName('.className')
To:
document.querySelector('.className')
you spelt it wrongly, it should be " getElementsByClassName ",
var objs = document.getElementsByClassName("stopButton");
var stopMusicExt = objs[0]; //retrieve the first node in the stack
//your remaining function goes down here..
document['player'].stopMusicExt(ta.value);
ta.value = "";
document.getElementsByClassName - returns a stack of nodes with more than one item, since CLASS attributes are used to assign to multiple objects...
it should be getElementsByClassName NOT getElementByClassName ==> you missed "s" in Elements
const collectionItems = document.getElementsByClassName('.item');
document.querySelectorAll works pretty well and allows you to further narrow down your selection.
https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
document.getElementByClass is not a function
Yes, it is not a function nor method because it should be document.getElementsByClassName
enter code here
var stopMusicExt = document.getElementByClass("stopButton").value;
stopButton.onclick = function() {
var ta = document.getElementByClass("stopButton");
document['player'].stopMusicExt(ta.value);
ta.value = "";
};
// .value will hold all data from class stopButton
The getElementByClass does not exists, probably you want to use getElementsByClassName. However you can use alternative approach (used in angular/vue/react... templates)
function stop(ta) {
console.log(ta.value) // document['player'].stopMusicExt(ta.value);
ta.value='';
}
<input type="button" onclick="stop(this)" class="stopMusic" value='Stop 1'>
<input type="button" onclick="stop(this)" class="stopMusic" value='Stop 2'>
If you wrote this "getElementByClassName" then you will encounter with this error "document.getElementByClass is not a function" so to overcome that error just write "getElementsByClassName". Because it should be Elements not Element.

Delete from all elements of the same class

I was looking for a way to search through all elements of the same class and remove any as these were causing unwanted gaps in my page layout.
Initially I used this code:
var el = document.querySelector('.offer');
el.innerHTML = el.innerHTML.replace(' ', '');
But this only finds the first node with the class of offer so isn't much use.
I'm answering my own question because I had to piece it together from a number of posts on here as well as other sites and I hope it helps others in my position.
Firstly I needed to use .queryselectorAll instead of .querySelector to return all elements with the offer class.
But the next line wont work since .queryselectorAll returns a string of nodes rather than just the first one it comes across.
el.innerHTML = el.innerHTML.replace(' ', '');
The solution is to loop through each element and replace each instance of
var el = document.querySelectorAll('.offer');
for(var i = 0; i < el.length; i++){
el[i].innerHTML = el[i].innerHTML.replace(' ', '');
}

Giving a different id to each child of an element

First question ever, new to programming. I'll try to be as concise as possible.
What I want to do is to create a bunch of children inside a selected div and give each of them specific html content (from a predefined array) and a different id to each child.
I created this loop for the effect:
Game.showOptions = function() {
var i = 0;
Game.choiceElement.html("");
for (i=0; i<Game.event[Game.state].options.length; i++) {
Game.choiceElement.append(Game.event[Game.state].options[i].response);
Game.choiceElement.children()[i].attr("id","choice1");
}
};
Using the predefined values of an array:
Game.event[0] = { text: "Hello, welcome.",
options: [{response: "<a><p>1. Um, hello...</p></a>"},
{response: "<a><p>2. How are you?</p></a>"}]
};
This method does not seem to be working, because the loop stops running after only one iteration. I sincerely have no idea why. If there is a completely different way of getting what I need, I'm all ears.
If I define the id attribute of each individual p inside the array, it works, but I want to avoid that.
The idea is creating a fully functional algorithm for dialogue choices (text-based rpg style) that would work with a predefined array.
Thanks in advance.
The problem with your loop as I see it could be in a couple different places. Here are three things you should check for, and that I am assuming you have but just didn't show us...
Is Game defined as an object?
var Game = {};
Is event defined as an array?
Game.event = new Array();
Is Game.state returning a number, and the appropriate number at that? I imagine this would be a little more dynamic then I have written here, but hopefully you'll get the idea.
Game.state = 0;
Now assuming all of the above is working properly...
Use eq(i) instead of [i].
for (var i = 0; i<Game.event[Game.state].options.length; i++) {
Game.choiceElement.append(Game.event[Game.state].options[i].response);
Game.choiceElement.children().eq(i).attr("id","choice" + (i + 1));
}
Here is the JSFiddle.

JavaScript: How to remove tags from node?

In a previous question someone put me on to "rangy" http://code.google.com/p/rangy/. It's interesting even if I don't fully understand it. I am not a JavaScript person. However, I have managed to do most things with it that I need with the exception of 1. The concept is a very basic RTE, just bold, italic etc. I managed that, created a link - done that too, OK what might have taken a JS guy 2 mins has taken me hours and hours - frustrating but I think I am learning a bit - very slowly. Anyhow, using rangy I can create (excuse poor code) an href link like this:
$('#linkbut').live('click',function(){
var sel = rangy.getSelection();
var range = sel.getRangeAt(0);
range.splitBoundaries();
var textNodes = range.getNodes([3]);
for (var i = 0, len = textNodes.length; i < len; ++i) {
var newLink = document.createElement('a');
newLink.setAttribute('href','test.html');
var linkText = document.createTextNode(sel);
var parent = textNodes[i].parentNode;
parent.insertBefore(newLink,textNodes[i]);
newLink.appendChild(linkText);
range.deleteContents();
}
});
#linkbut is a simple HTML button and the actual href (test.html) above will come from the value of an input field and not be "hard coded". But what I cannot get done is "delete" the link if I want to remove it.
Further explanation: Once the link is created I may want to delete it so I have tried the "reverse" of the code above - obviously no good, so have got "this far":
$('#deletelink').live('click',function(){
var sel = rangy.getSelection();
var range = sel.getRangeAt(0);
range.splitBoundaries();
var textNodes = range.getNodes([3]);
var txt = sel.toString();
range.deleteContents();
var replaceText = document.createTextNode(txt);
sel.appendChild(replaceText);
});
What I really would like to do (may not be possible) is to have some "generic" function that removes ANY tag element from a node in the above what I am trying to do is:
Get the range - sel = rangy.getSelection();
Turn "sel" into a string variable var txt = sel.toString();
Delete the content - including the a elements range.deleteContents();
then
Replace the deleted with the "text" version var replaceText = document.createTextNode(txt); sel.appendChild(replaceText);
I get "so far" the content is deleted BUT I cannot get the "new - text replacement" to function.
Hope all is clear - cos it isn't to me ;)
I know an old question but I had the same issue and found a viable solution here.
var el = document.getElementsByTagName('span')[0]; // Get the element in question
var pa = el.parentNode;
while(el.firstChild) {
pa.insertBefore(el.firstChild, el);
}
pa.removeChild(el);
pa.normalize();
Edit: The normalize() method is important so that you don't have a bunch of adjacent text nodes. It causes all the text nodes to be aggregated into one text node again.
For your exact question, you could iterate over all the nodes and then execute the above code.
You should probably look up on how to do nested selection in jQuery and as NeXXeuS said you should look into removing the contents via .html() on your selected method.
If you have:
<div id="mydiv"></div>
And you run: `
$('#mydiv').append('Test Link');
The html will look like:
<div id="mydiv">Test Link</div>
You can this select the link with:
$('#mydiv a');
You can delete it by doing:
$('#mydiv').html('');

Is Greasemonkey not capable of using jQuery's full power?

I'm trying to find an element using jQuery, but it is not working.. I found out that this kind of selector can't be done in Greasemonkey:
($("#app7019261521_hover_container > [id^=app7019261521_the_coin]"))
Please help me translate this into raw Javascript. This kind of selector is hardcore to do in Javascript. Please help me Javascript gurus!
This should do it, and now I remember why I started using jQuery:
var children = document.getElementById('app7019261521_hover_container').childNodes;
var ids = []; //to store the IDs of all matching elements
for(var i = 0; i < children.length; i++)
{
//indexOf returns zero is subject starts with passed string
if(children.item(i).id.indexOf('app7019261521_the_coin') == 0)
{
alert('Got One!');
ids.push(children.item(i).id);
}
}
Since you are targeting directly to Firefox, you may want to give a look to the Selectors API implemented on Firefox 3.5.
Check the document.querySelectorAll function:
var elements = document.querySelectorAll("#app7019261521_hover_container > [id^=app7019261521_the_coin]")

Categories

Resources