Like the title says after I change the src to the value during the rollEvent function, the image doesn't change. When I print the value of display.src to console it is correct. But the actual document doesn't change the src value for the img tag with the class of display_box. Am I missing something here?
jsfiddle.net/bNL5C/3/
window.onload = function eventsLoad (elem, display) {
elem = document.getElementsByClassName('images');
display = document.getElementsByClassName('display_box');
function rollEvent(e) {
var sourceURL = this.src;
console.log(sourceURL);
display.src = sourceURL;
console.log(display.src);
};
console.log(elem);
console.log(display);
for (var i = 0; i < elem.length; i++) {
elem[i].addEventListener('mouseover', rollEvent, false);
console.log('Added event listener to ' + elem[i]);
};
}
getElementsByClassName returns NodeList, so you should change display.src = sourceURL:
function rollEvent(e) {
var sourceURL = this.src;
display[0].src = sourceURL; // <--- change here
console.log(display.src);
};
Demo: http://jsfiddle.net/bNL5C/4/
or use display = document.querySelector('.display_box'); instead.
Try this... Change:
document.getElementsByClassName returns an array - display is a list. Try changing
display.src = sourceURL;
To:
display[0].src = sourceURL;
Related
I have this JQuery function:
var objects = document.querySelectorAll('object');
// Iterate through objects
$('object').each( function() {
var link = $(this).attr('data');
$(this).append('click here');
});
It goes through all <object> items in a page and appends a link to the end of them (all of the objects in this case are used to create an embed document.) However, I want to edit the function so that it also edits an attribute in the object tag, preferably changing the name attribute, and also add an if statement to check to see if the object tag contains this new name.
You can use .attr() to get/set the name attribute, also you can use .is() along with attribute selector
// Iterate through objects
var $objects = $('object');
$objects.each(function() {
var $this = $(this);
$this.append('<a href="' + $this.attr('data')
'">click here</a>');
var nametoset = ''; //some logic to find the name
if ($objects.is('[name="' + nametoset + '"]')) {
//name already exists so do something
} else {
$this.attr('name', nametoset);
}
});
$('object').each( function() {
var link = $(this).attr('data');
var newlink = $('click here');
newLink.attr("name","jonny");
$(this).append(newLink);
});
OR
$('object').each( function() {
var link = $(this).attr('data');
var newname = "jonny";
var newlink =$ ('click here');
$(this).append(newLink);
});
hey i create an Element with id and an eventListener. so when i click a link i want to get the id.
But i don't have Control of this created Element. "cannot set property ... of null".
function insertLink(text,link,window,underline)
{
var doc = document.getElementById("iframe_editor").contentWindow.document;
var sel = doc.getSelection();
var count = parseInt(document.getElementById("counter").value);
if (sel.rangeCount > 0)
{
count ++;
document.getElementById("counter").value = count;
var range= sel.getRangeAt(0);
myParent=document.getElementById("iframe_editor").contentWindow.document.body;
alink=document.createElement("a");
var text = document.createTextNode(document.getElementById("linktext").value);
alink.href = document.getElementById("linkhref").value;
alink.id = "testid"+count;
alink.appendChild(text);
myParent.appendChild(alink);
range.insertNode(alink);
alink.addEventListener( 'click', function(){
loadElement(count.toString());
},count );
}
}
function loadElement(t)
{
alert(t);
document.getElementById("testid"+t).innerHTML = "<a href = ''>Test</a>";
}
When i check the variable t in loadElement i get back the right number. But i cannot Change this element with innerhtml.
why not?
The link you inserted does not exist in your actual web page, but inside your iframe. So, you have to access it from the iframe:
document.getElementById("iframe_editor").contentWindow.document.getElementById("testid"+t).innerHTML = "<a href = ''>Test</a>";
The code below gets info from xml file.
I succesfully presents the id and name of each planet with a button.
I want to add an onclick event on the button.
Problem now is: it does add the onclick event but only on the last button created in the loop.
What am i doing wrong? Why doesnt it create a onclick event for each button, but only for the last one in loop?
function updatePlaneten() {
var valDiv, planets, valButton, textNode;
// Get xml files
planets = this.responseXML.getElementsByTagName("planeet");
// loop through the <planet> tags
for (var i = 0; i < planets.length; i++) {
valDiv = ''; // clear valDiv each time loop starts
// Get the id and the name from the xml info in current <planet> tag
valDiv += planets[i].getElementsByTagName("id")[0].childNodes[0].nodeValue + "<br>";
valDiv += planets[i].getElementsByTagName("name")[0].childNodes[0].nodeValue + "<br>";
document.getElementById("planetenID").innerHTML += valDiv + "<br>";
// Create button with a value and pass in this object for later reference use (valButton.object=this)
valButton = document.createElement("input");
// valButton.setAttribute("planeetID", planets[i].getElementsByTagName("id")[0].childNodes[0].nodeValue);
valButton.setAttribute("value", 'Meer info');
valButton.setAttribute("type", 'button');
valButton.id = (i + 1);
valButton.object = this;
//
// Here is the problem i cant get fixed
//
//valButton.onclick = function(){ showinfo(); }
valButton.addEventListener('click', showinfo);
// Place the button on screen
document.getElementById("planetenID").appendChild(valButton);
}
}
// simple function to check if it works
function showinfo() {
console.log(this.object);
console.log(this.id);
}
The trouble is this line:
document.getElementById("planetenID").innerHTML += valDiv + "<br>";
When you set innerHTML the content currently in there gets destroyed and replaced with the new html, meaning all your old buttons are now destroyed and new ones are created. The previously attached event listeners do not get attached to the new buttons.
Instead simply create a div/span or whatever container would best help, add your planet text or whatever to it and then use appendChild
valDiv = document.createElement("div");
var id = planets[i].getElementsByTagName("id")[0].childNodes[0].nodeValue;
var name = planets[i].getElementsByTagName("name")[0].childNodes[0].nodeValue;
valDiv.innerHTML = id+"<br>"+name+"<br>";
document.getElementById("planetenID").appendChild(valDiv);
You could also use insertAdjacentHTML
var id = planets[i].getElementsByTagName("id")[0].childNodes[0].nodeValue;
var name = planets[i].getElementsByTagName("name")[0].childNodes[0].nodeValue;
valDiv = id+"<br>"+name+"<br>";
document.getElementById("planetenID").insertAdjacentHTML("beforeend",valDiv);
function updatePlaneten() {
var valDiv, planets, valButton, textNode;
// Get xml files
planets = this.responseXML.getElementsByTagName("planeet");
// loop through the <planet> tags
for (var i = 0; i < planets.length; i++) {
(function(num){
valDiv = document.createElement("div");
// Get the id and the name from the xml info in current <planet> tag
var id = planets[num].getElementsByTagName("id")[0].childNodes[0].nodeValue + "<br>";
var name = planets[num].getElementsByTagName("name")[0].childNodes[0].nodeValue + "<br>";
valDiv.innerHTML = id+"<br>"+name+"<br>";
document.getElementById("planetenID").appendChild(valDiv);
// Create button with a value and pass in this object for later reference use (valButton.object=this)
valButton = document.createElement("input");
// valButton.setAttribute("planeetID", planets[i].getElementsByTagName("id")[0].childNodes[0].nodeValue);
valButton.setAttribute("value", 'Meer info');
valButton.setAttribute("type", 'button');
valButton.id = (num + 1);
valButton.object = this;
// FIX: PASS showinfo TO AN ANONYMOUS FUNCTION CONTAINING THE OBJECT
valButton.addEventListener('click', function(){
showinfo(valButton);
});
// Place the button on screen
document.getElementById("planetenID").appendChild(valButton);
}(i));
}
}
// simple function to check if it works
function showinfo(valButton) {
console.log(valButton.object);
console.log(valButton.id);
}
Can you use the this tag for the onclick on an HTML tag?
Here's my JS code...
function changeImage() {
this/*<-- right there <--*/.src=a;
}
document.getElementsByTagName('img').onclick = function(){
changeImage();
} ;
Am I doing something wrong?
Use it this way...
function changeImage(curr) {
console.log(curr.src);
}
document.getElementsByTagName('img').onclick = function(){
changeImage(this);
} ;
You could use the .call() method to invoke the function with the context of this.
In this case, you would use:
changeImage.call(this)
Example Here
function changeImage() {
this.src = 'http://placehold.it/200/f00';
}
document.getElementsByTagName('img')[0].onclick = function(){
changeImage.call(this);
};
As a side note, getElementsByTagName returns a live HTMLCollection of elements. You need to apply the onclick handler to an element within that collection.
If you want to apply the event listener to the collection of elements, you iterate through them and add event listeners like this:
Updated Example
function changeImage() {
this.src = 'http://placehold.it/200/f00';
}
Array.prototype.forEach.call(document.getElementsByTagName('img'), function(el, i) {
el.addEventListener('click', changeImage);
});
Or you could simplify it:
Example Here
Array.prototype.forEach.call(document.getElementsByTagName('img'), function(el, i) {
el.addEventListener('click', function () {
this.src = 'http://placehold.it/200/f00';
});
});
You are doing two things wrong.
You are assigning the event handler to a NodeList instead of to an element (or set of elements)
You are calling changeImage without any context (so this will be undefined or window depending on if you are in strict mode or now).
A fixed version would look like this:
var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
images[i].onclick = function () {
changeImage.call(this);
};
}
But a tidier version would skip the anonymous function that does nothing except call another function:
var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
images[i].onclick = changeImage;
}
And modern code would use addEventListener.
var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
images[i].addEventListener('click', changeImage);
}
However, images are not interactive controls. You can't (by default) focus them, so this approach would make them inaccessible to people who didn't use a pointing device. Better to use controls that are designed for interaction in the first place.
Generally, this should be a plain button. You can use CSS to remove the default padding / border / background.
If you can't put a button in your plain HTML, you can add it with JS.
var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
var image = images[i];
var button = document.createElement('button');
button.type = "button";
image.parentNode.replaceChild(button, image);
button.appendChild(image);
button.addEventListener('click', changeImage);
}
function changeImage(event) {
this.firstChild.src = a;
}
I want to add Rows to a Table that already exists and each row has a onclick attribute. The problem is that each row needs to call the function with another parameter. At The moment no matter in what row i click the function is called with the parameter of the last row in the table.
This is how i add the rows to the table :
table = document.getElementById('ProgramTable');
table.style.visibility = "visible";
tableBody = document.getElementById('ProgrammTableBody');
tablelength = jsonObj0.data.map.programs.length;
// Check if there is already a Table, if so
// remove the Table
if (tableexists) {
removetable();
}
for ( var i = 0; i < tablelength; i++) {
channel = jsonObj0.data.map.programs[i].programServiceName;
frequency = jsonObj0.data.map.programs[i].programIdentifier;
imagelink = "../image/image.jsp?context=tuner&identifier="
+ channel;
var row = document.createElement("tr");
row.setAttribute("id", i);
row.onclick = function() {
tuneProgram(frequency)
};
var channelCell = document.createElement("td");
var imageCell = document.createElement("td");
var imageElement = document.createElement("IMG");
var frequencyCell = document.createElement("td");
channel = document.createTextNode(channel);
frequency = document.createTextNode(frequency);
channelCell.appendChild(channel);
frequencyCell.appendChild(frequency);
imageElement.setAttribute("src", imagelink);
imageElement.setAttribute("width", "40");
imageElement.setAttribute("height", "40"); // TODO OnError
// hinzufügen und evtl
// Css Style für Texte
// siehe Tabellencode
imageCell.appendChild(imageElement);
row.appendChild(channelCell);
row.appendChild(frequencyCell);
row.appendChild(imageCell);
tableBody.appendChild(row);
}
So the tune function should be called with the specific frequency parameter but it seems like he is overwriting the onclick parameter everytime so the last one is in there for every row. But why is that so? is he adding the onclick Attribute to every row in that table? I don't get it.
Thanks for your help!
Replace
row.onclick = function() {
tuneProgram(frequency)
};
with
row.onclick = (function(frequency) {return function() {tuneProgram(frequency);};})(frequency);
This "anchors" the value of frequency by creating a new closure for it.
You need to do something like this:
for (var i = 0; i < tablelength; i++) {
(function(i) {
//your code here
})(i);
}
Frequency is being referenced when you click - so if the variable changes, it changes every click element. For example, the first row sets a frequency of one and the last row sets a frequency of two. When the onclick runs it isn't referenced to a value, its referenced to a variable in the chain and gets the current value of two.
because your frequency is a global value, so there is only one frequency that every function refer to it;you can cache it in a closure
something like this:
var programTable = document.getElementById('ProgramTable');
programTable.style.visibility = "visible";
programmTableBody = document.getElementById('ProgrammTableBody');
tablelength = jsonObj0.data.map.programs.length;
if (tableexists) {
removetable();
}
function newTabRow ( table, name, identifier ) {
var link = "../image/image.jsp?context=tuner&identifier=" + name,
row = table.insertRow();
row.innerHTML = '<td>' + name + '</td><td><img width="40" height="40" src="'+link+'" alt="''" /></td><td>'+ identifier +'</td>';
row.onclick = function ( ) {
tuneProgram ( identifier );
}
}
for (var i = tablelength; i-- > 0; ) {
program = jsonObj0.data.map.programs[i];
newTabRow ( programTable, program.programServiceName, program.programIdentifier );
}
Be careful I have a function on top of my page with name "show_field_setting". my function get to value and do something. I have a for loop and in my loop i change 'type' and 'id' for each element. you can see one part inside of my for loop below. finally I add my new element to my div with element id 'my_element_id'. If you want to set a function to your created element you need use something like this:
var new_child = document.createElement('div');new_child.id = id;
new_child.href = "javascript:;";
new_child.onclick = (function (type, id) {
return function() {
show_field_setting (type, id);
};
})(type, id);
document.getElementById('my_element_id').appendChild(new_child);
if you have on argumant in your function only, use this:
var new_child = document.createElement('div');
new_child.href = "javascript:;";
new_child.onclick = (function (your_value) {
return function() {
your_function_name (your_value);
};
})(your_value);
document.getElementById('your_element_id').appendChild(new_child);
finally i don't know why. any way if you are not in loop condition like "while", "for" or even "switch" you can use easy below code line:
var new_child = document.createElement('div');
new_child.href = "javascript:;";
new_child.onclick = function(){your_function_name (your_value_1, your_value_2 , ...)};
document.getElementById('your_element_id').appendChild(new_child);
Have Fun ;) :)