How can I pass an object to a function in innerHTML (JavaScript)? - javascript

How can I pass an object to a function in innerHTML?
Here is an example:
function clickme()
{
var coord = {x:5, y:10};
testimageih(coord);
}
function testimageih(coord)
{
var html = "<img id=\"sam1\" border=\"0\" name=\"sam1\" src=\"sample.gif\" " +
"onLoad=\"ImageOnLoad(" + coord + ");\"></img>";
document.getElementById("content").innerHTML = html;
}
function ImageOnLoad(coord)
{
if (coord) alert("Success");
else alert("Fail");
}
How can I pass this object, coord? It's my only other recourse, at the moment, is passing coord.x and coord.y, instead of the object.
Thank you.

The simplest way is to create an image, attach the event handler and insert the element using DOM methods.
function testimageih(coord)
{
var img = document.createElement('img');
img.id = 'sam1';
img.border = 0;
img.name = 'sam1';
img.src = 'sample.gif';
img.onload = function() {
ImageOnLoad(coord);
};
document.getElementById('content').appendChild(img);
}
Note that this has one difference to the code you have above: it doesn't remove any elements currently in #content. If that will happen, you will have to do the removal separately.

You could use document.createElement instead of innerHTML.
// Create the element
var element = document.createElement('img');
element.setAttribute('border', 0);
element.setAttribute('name', 'sam1');
element.setAttribute('src', 'sample.gif');
// Attach onLoad handler to it (passing it the object)
element.onload = function() { ImageOnLoad(coord) };
// Replace the contents of your... div?
var content = document.getElementById("content")
content.innerHTML = '';
content.appendChild(element);

The way you are implementing it now, yes--you're creating HTML as a string, and embedding JavaScript within that string; your options are limited.
And geez, use single-quotes around the html var so you don't have to escape everything :(

Related

Using class instead of id in JS to do an action

First, sorry I'm not good with javascript.
HTML:
<div id="Comment-ID">
<p class="comment-content">...</p>
</div>
The javascript: (Edit: Added the whole code)
<script type='text/javascript'>
function autoloadmore() {
var loadmoreClass = document.getElementsByClassName("loadmore")[0];
var loadmoreChild = loadmoreClass.querySelector('a')
if (loadmoreClass) {
loadmoreChild.click();
}
}
//<![CDATA[
function InsertarImagenVideo(id) {
var IDelemento = document.getElementById(id),
sustituir = IDelemento.innerHTML;
sustituir = sustituir.replace(/\[img\](.[^\]]*)\[\/img\]/ig, "<img class='img-comentarios' src='$1'\/>");
document.getElementById(id).innerHTML = sustituir;
}
//]]>
window.onload = function() {
autoloadmore();
setTimeout(function(){
InsertarImagenVideo('Comment-ID');
},3000);
};
</script>
"InsertarImagenVideo" replaces some text inside with an image. Instead of using it on "Comment-ID", I want to use it on "Comment-class".
Note: I can't edit the HTML.
I couldn't find anything when I searched, or maybe I didn't know how to look. Can someone help me with this?
You can use document.querySelector to select an element by class:
Update this line:
var IDelemento = document.getElementById(id),
to var IDelemento = document.querySelector(id),
and pass the class selector to your method InsertarImagenVideo
setTimeout(function(){
InsertarImagenVideo('.comment-content');
},3000);
I found a simple way to insert an image into the <p class="comment-content">...</p> element by grabbing the parent <div id="Comment-ID">.
I'm assuming that you need to grab the unique id to then access the inner <p> element to replace the existing text with an image. This code grabs the unique id element, then grabs the first <p> tag using .getElementsByTagName('p')[0]. One thing I did add is a proper image load script to update the <p> tag with the image once it has been loaded (maybe this removes the need for that setTimeout function you have?).
let classElement = document.getElementById("Comment-ID").getElementsByTagName('p')[0];
let imageObject = new Image();
imageObject.src = `https://www.clipartmax.com/png/full/1-14442_smiley-face-png-smiley-png.png`;
imageObject.onload = function() {
classElement.innerHTML = `<img id="myImg" src="${imageObject.src}" />`;
let imageElement = document.getElementById(`myImg`);
imageElement.width = 100;
imageElement.height = 100;
};
Here's a JSFiddle demo of the upper code in action.
Hope this helps :)

How to convert dynamically added elements into JSON and back

Quick context: This is an application that mimics a magnet board. I want to save the location and id of all draggable elements and later load the file and set those properties and create/delete missing/unnecessary elements. To save the files I utilize Node.js and Electron.
I thought using JSON would be sensible since it can convert directly from JS but how does one do that with an unknown amount of elements?
This Javascript Code adds one of those elements to my page when the corresponding button is pressed:
$("#item1").mousedown(function (e){
var newpin = document.createElement("DIV");
var pinimage = document.createElement("IMG");
pinimage.setAttribute("src", "Media/2D_Container_Alfa.jpg");
pinimage.setAttribute("id", "Alfa");
pinimage.setAttribute("height", "70px");
newpin.setAttribute("position","relative");
newpin.setAttribute("top","20px");
newpin.setAttribute("left","140px");
newpin.setAttribute("display","block");
newpin.setAttribute("class", "draggable ui-draggable ui-draggable-handle");
newpin.appendChild(pinimage);
document.body.appendChild(newpin);
});
$("#item2").mousedown(function (e){
var newpin = document.createElement("DIV");
var pinimage = document.createElement("IMG");
pinimage.setAttribute("src", "Media/2D_Container_Bravo.jpg");
pinimage.setAttribute("id", "Bravo");
pinimage.setAttribute("height", "70px");
newpin.setAttribute("class", "draggable ui-draggable ui-draggable-handle");
newpin.appendChild(pinimage);
document.body.appendChild(newpin);
});
-
You could create the JSON variable outside any functions that might reduce its scope, and then add them in as and when you need to.
let myJson = {};
function onMouseDown(event) {
let thisId = event.id;
myJson[thisId] = location;
}
You mean
localStorage.setItem("draggable",JSON.stringify($('.draggable').map(function(){
return this.id
}).get()));
or
$.post("saveonserver",{"data":JSON.stringify($('.draggable').map(
function(){
return this.id
}).get()
});

How to add event to element created with js?

I created the script below. It puts the body in a div, as desired. However, the event handler fails. I'm sure it's a simple error.
body_html = document.body.innerHTML;
new_html = "<div id='realBody'>" + body_html + "</div>";
document.body.innerHTML = new_html;
document.body.getElementById("realBody").addEventListener("mouseover", function(event) {alert('body');});
How to make the event work? (Feel free to rewrite the whole thing if there's a better (simpler) way.
Edit: This works, some comments say it's the wrong way to put the body into a div, but i see no problems:
body_html = document.body.innerHTML;
new_html = "<div id='realBody'>" + body_html + "</div>";
document.body.innerHTML = new_html;
document.getElementById("realBody").addEventListener("mouseenter", function(event) {alert('body');});
thx!
You need to change document.body.getElementById() to document.getElementById()
document.getElementById("realBody").addEventListener("mouseover", function(event) {alert('body');});
You should attach event listener like,
body_html = document.body.innerHTML;
new_html = "<div id='realBody'>" + body_html + "I am border</div>";
document.body.innerHTML = new_html;
document.getElementById("realBody").addEventListener("mouseover", function (event) {
alert('body');
});
DEMO
The error you're receiving is probably because of this line:
document.body.getElementById("realBody").addEventListener("mouseover", function (event) { alert('body'); });
you need to modify it to this:
document.getElementById("realBody").addEventListener("mouseover", function (event) { alert('body'); });
document.body.getElementById() just needs to be document.getElementByid()
A more proper way to add elements to the DOM would be to do something like below:
var divEl = document.createElement("div");
divEl.id = "realBody";
var textNode = document.createTextNode("Hover over me");
divEl.appendChild(textNode);
document.body.appendChild(divEl);
divEl.onmouseover = function (event) {
alert('body');
}
As everybody explained, you need to call the getElementById() on the document object, not in an element.
But your code will loose any event handlers attached to the elements prior to your code execution as you are clearing the html and creating a new dom structure you overwritting the innerHTML.
Instead just move the existing dom to the new element like
var wrapper = document.createElement('div');
wrapper.id = 'realBody';
while (document.body.firstChild) {
wrapper.appendChild(document.body.firstChild);
}
document.body.appendChild(wrapper);
wrapper.addEventListener("mouseover", function (event) {
console.log('body');
});
Demo: Fiddle

Javascript Array Undefined

I keep getting the error links[i] is undefined.
I define it explicitly and yet it keeps giving me that error -- any ideas?
I am trying to do unobtrusive image rolovers on 5 links that I have.
function loadImages(){
path = 'uploads/Splash-4/nav/';
links = new Array();
for (i=1;i<=5;i++){
var id = "link-"+i;
var defaultState = '<img src="' +path+i+'.jpg" border="0" />';
links[i] = document.getElementById(id);
// Place all image linksinto anchor
links[i].innerHTML = defaultState;
// What to do on mouseover
links[i].onmouseover = function() {
links[i].innerHTML = '<img src="' +path+i+'a.jpg" border="0" />';
}
// What to do on mouse oUt
links[i].onmouseout = function() {
links[i].innerHTML = defaultState;
}
}
}
window.onload = loadImages;
HTML:
<br />
<br />
<a href="?page=free-home-appraisal" id="link-4" /></a><br />
<br />
First off, you should be saying:
var links = [];
It's generally discouraged to use the Array constructor itself, and by not specifying var, you're making the links variable reside in the global space, which is generally bad.
Now, as to your actual problem.
Your event handlers are carrying a reference to the path and i variables from the outer scope, but by the time they're actually encountered, the variable i has the value 6 -- not what you intended at all! In order to fix that, you can change:
// What to do on mouseover
links[i].onmouseover = function() {
links[i].innerHTML = '<img src="' +path+i+'a.jpg" border="0" />';
}
// What to do on mouse oUt
links[i].onmouseout = function() {
links[i].innerHTML = defaultState;
}
to
// What to do on mouseover
links[i].onmouseover = (function(path, i) {
return function () {
links[i].innerHTML = '<img src="' +path+i+'a.jpg" border="0" />';
};
})(path, i);
// What to do on mouseout
links[i].onmouseout = (function(i) {
return function () {
links[i].innerHTML = defaultState;
}
})(i);
This creates a new closure to hold the variables you want to capture. This way the inner i can still be, oh, 3 while the outer i goes to 6.
The problem is that when your onmouseover() function gets called, your variable i = 6 because your last iteration yielded i = 6, causing the loop to end. Therefore, you must protect i somewhere. For example :
function loadImages(){
path = 'uploads/Splash-4/nav/';
var links = [];
for (i=1;i<=5;i++){
(function(j) {
var id = "link-"+j;
var defaultState = '<img src="' +path+j+'.jpg" border="0" />';
links[j] = document.getElementById(id);
// Place all image linksinto anchor
links[j].innerHTML = defaultState;
// What to do on mouseover
links[j].onmouseover = function() {
links[j].innerHTML = '<img src="' +path+j+'a.jpg" border="0" />';
}
// What to do on mouse oUt
links[j].onmouseout = function() {
links[j].innerHTML = defaultState;
}
})(i); // call the anonymous function with i, thus protecting it's value for
// the mouseover/mouseout
}
}
Your code snippet doesn't include a declaration of the variable links. If you haven't defined it elsewhere (i.e., if it's a local variable), you'll need to do it here:
Instead of
links = new Array();
You could do
var links = new Array();
One example can be found here.
If you have declared it elsewhere, it could be that this line
document.getElementById(id);
is returning null.

obj is null, javascript

function init()
{
alert("init()");
/**
* Adds an event listener to onclick event on the start button.
*/
xbEvent.addEventListener(document.getElementById("viewInvitation"), "click", function()
{
new Ajax().sendRequest("31260xml/invitations.xml", null, new PageMaster());
xbEvent.addEventListener(document.getElementById("declinebutton"), "click", function ()
{
declineInvitation();
});
});
ok so what I have here is a event listerner function, the case is when viewInvitation is clicked , the program will fetch my xml file and run page master function where I created my decline button with id="declinebutton", however this does not work, the error message that i get is obj=null or the program could not find id = declinebutton, why is it so? I have created it when I called page master using dom. any help will be appreciated.
function PageMaster()
{
this.contentDiv = document.getElementById("content");
}
/**
* Builds the main part of the web page based on the given XML document object
*
* #param {Object} xmlDoc the given XML document object
*/
var subjectList;
var i;
PageMaster.prototype.doIt = function(xmlDoc)
{
alert("PageMaster()");
alert("Clear page...");
this.contentDiv.innerHTML = "";
if (null != xmlDoc)
{
alert("Build page...");
//create div Post
var divPost = document.createElement("div");
divPost.className = "post";
//create h1 element
var h1Element = document.createElement("h1");
var headingText = document.createTextNode("Invitations");
h1Element.appendChild(headingText);
//insert h1 element into div post
divPost.appendChild(h1Element);
subjectList = xmlDoc.getElementsByTagName("subject");
var groupList = xmlDoc.getElementsByTagName("group");
for (i = 0; i < subjectList.length; i++) //for each subject
{
var divEntry = document.createElement("div");
divEntry.className = "entry";
var subjectNum = subjectList[i].attributes[0].nodeValue;
var subjectName = subjectList[i].attributes[1].nodeValue;
var groupId = groupList[i].attributes[0].nodeValue;
var groupName = groupList[i].attributes[1].nodeValue;
var ownerId = groupList[i].attributes[2].nodeValue;
//set up the invitation table attributes
var table=document.createElement("table");
table.width = 411;
table.border = 3;
table.borderColor = "#990000"
var input=document.createElement("p");
var inputText=document.createTextNode("You are invited to join " + groupName + "(groupId : " + groupId +")");
input.className="style11";
var blank=document.createElement("nbps");
input.appendChild(inputText);
var acceptButton=document.createElement("input");
acceptButton.type="button";
acceptButton.id="acceptbutton";
acceptButton.value="accept";
var declineButton=document.createElement("input");
declineButton.type="button";
declineButton.id="declinebutton";
declineButton.value="decline";
table.appendChild(input);
table.appendChild(acceptButton);
table.appendChild(declineButton);
divEntry.appendChild(table);
var blankSpace = document.createElement("p");
divEntry.appendChild(blankSpace);
divPost.appendChild(divEntry);
}
//insert div post into div content
this.contentDiv.appendChild(divPost);
}
};
/**function getValueOf()
{
return i;
}**/
function declineInvitation()
{
alert("decline");
}
function acceptInvitation()
{
alert("hello");
/**var pos=getValueOf();
alert(subjectList[pos].attributes[0].nodeValue);**/
}
That's my page master function, and I definitely have created the button. but it does not work.
Try calling your function like this:
window.onload=init;
The javascript runs as the page loads. At that point, the element does not yet exist in the DOM tree. You'll need to delay the script until the page has loaded.
The example you gave doesn't create the "Decline" button, as your question suggests it should. If it should, you might want to look at that.
Of course, if the button already exists, please disregard this answer.
You have a listener inside a listener. Is that right?
What about this?:
function init(){
alert("init()");
/** * Adds an event listener to onclick event on the start button. */
xbEvent.addEventListener(document.getElementById("viewInvitation"), "click", function()
{
new Ajax().sendRequest("31260xml/invitations.xml", null, new PageMaster());
}
xbEvent.addEventListener(document.getElementById("declinebutton"), "click", function ()
{
declineInvitation();
});
As far as I understand, you create button with id="declinebutton" for each entry from xml, is that right?
If yes, I'd suggest you to generate different id's for each button (for example, append line index to 'declinebutton', so you have buttons 'declinebutton0', 'declinebutton1' an so on), and assign event listener to buttons separately in the loop.

Categories