Assigning an event function to many elements with pure Javascript - javascript

I'm building a table of links containing images with a javascript function. Here's the code:
function populateGrid(dataArray) {
var table = document.createElement("table");
table.id = "data-table";
var row = document.createElement("tr");
for (var i = 1; i <= dataArray.length; i++) {
var tableItem = document.createElement("td");
var linkContainer = document.createElement("a");
var itemImage = document.createElement("img");
linkContainer.href = dataArray[i - 1].url;
linkContainer.target = "_blank";
itemImage.onmouseover = function(e) {
linkHover(e);
};
itemImage.onmouseout = function(e) {
linkBlur(e);
};
itemImage.src = dataArray[i - 1].logo;
linkContainer.appendChild(itemImage);
tableItem.appendChild(linkContainer);
row.appendChild(tableItem);
// This checks to see if it's time to make a new row, in order to keep the table a square
if (i % Math.round(Math.sqrt(dataArray.length + 1)) === 0) {
table.appendChild(row);
row = document.createElement("tr");
}
}
table.appendChild(row);
document.getElementById('inject').appendChild(table);
}
I'm having issues with assigning the "onmouseover" and "onmouseout" events to each individual table item. Lint is telling me that it's bad form to assign functions within a for-loop, and it definitely seems messy to me. I've tried this:
itemImage.onmouseover = linkHover(e);
But when I do it this way, I get the error: "Uncaught ReferenceError: e is not defined". I need some context as to which element is causing the linkHover and linkBlur functions to be called, as I change the border of the corresponding image as seen in this .gif:
(I don't have enough reputation to post images, so here's the link: http://i.imgur.com/6r8rQQp.gifv)
My linkHover and linkBlur functions are as follows:
function linkHover(e) {
e.target.className = "green-border";
}
function linkBlur(e) {
e.target.className = "";
}
My question is: how should I do this better? I'm sure there must be a cleaner way that doesn't give lint errors.
Thanks in advance for your help.
EDIT:
Okay, so following gcampbell's advice, I'm assigning the event listener to the table like so:
var table = document.createElement("table");
table.onmouseover = function(e) {
linkHover(e);
};
table.onmouseout = function(e) {
linkBlur(e);
};
And then I check to make sure the target was an img:
function linkHover(e) {
if (e.target.tagName == "IMG") {
e.target.className = "green-border";
}
}
Is this bad form? Should I just condense these functions into the event assignments?
Thanks.

Related

How to get the img id for dynamically building IMG tags based on click like Share or Like or Comment

Good Evening Everyone.
Background: I am getting list of images from a Mongo Database and then I am calling ajax once to load those data in to particular div.
Here I am building those img tags dynamically and then appending it to a div.
Now I am trying to get the img id based on user operation, lets say clicks on 'share button' for a particular img, then I have to get the image id, and then have to look search the DB with that image id.
My code after the ajax call is:
function showImages(imageList) {
for ( var i = 0, len = imageList.length; i < len; i++) {
var elem = document.createElement("img");
elem.src = 'getImg/' + imageList[i][0] + '/' + imageList[i][1];
elem.id = imageList[i][2];
alert(elem.id);
elem.height = '100';
elem.width = '100';
elem.alt = 'SPF HYD';
/* $("a[id=shareImage]").click(function(){
var qwerty = $("img", $(this).parent()).attr("id");
alert('image id is after anchor by click...'+qwerty);
}); */
var image = document.getElementById("imageLoad");
image.appendChild(elem);
}
}
Could any one help me to get the image id onclick or any button trigger?
I threw a quick demo together to demonstrate what I meant. It's made possible using jQuery event Delagation
function showImages(imageList) {
for ( var i = 0, len = imageList.length; i < len; i++) {
var elem = document.createElement("img");
elem.src = 'getImg/' + imageList[i][0] + '/' + imageList[i][1];
elem.id = imageList[i][2];
console.log(elem.id);
elem.height = '100';
elem.width = '100';
elem.alt = 'SPF HYD';
var image = document.getElementById("imageLoad");
image.appendChild(elem);
}
}
//The event handler is registered on the document object - the second argument here is the delegate, <img>
$(document).on("click", "img", function(e) {
alert($(this).attr("id"));
});
var imageList = [[0, 1, 2], [3, 4, 5]]; //These values are merely for testing
showImages(imageList);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="imageLoad"></div>
Using Event Delegation is necessary here because your img tags are being dynamically generated, plus it's a lot cleaner to register one event handler for all img tags, rather than an event handler for each
Hope this helps
Use addEventListener function to add an Event Listener to your dynamically created element.
var div = document.getElementById("div");
var imgShare = document.createElement("img");
imgShare.src = "http://icons.iconarchive.com/icons/graphicloads/100-flat-2/128/share-2-icon.png";
imgShare.id = "post002";
imgShare.addEventListener("click", share);
div.appendChild(imgShare);
var imgLike = document.createElement("img");
imgLike.src = "http://www.brandsoftheworld.com/sites/default/files/styles/logo-thumbnail/public/102011/like_icon.png?itok=nkurUMlZ";
imgLike.id = "post001";
imgLike.addEventListener("click", like);
div.appendChild(imgLike);
function share(e){
alert("Share id:" + e.currentTarget.id);
}
function like(e){
alert("like id:" + e.currentTarget.id);
}
<div id="div"></div>
JSFiddle Link...

cloning html element doesnt seem to have prototype methods

I am trying to clone the contents of a modal before it disappears.
basically when the ok button is clicked it passes a clone of object to function like so
$ok.onclick = function(e){
if(params.ok)
var $cont = $content.cloneNode(true);
params.ok($cont);
closeSlert($slert);
}
however later I am trying to use getElementById() but it returns that this is not a function
I thought that Element.clone clones the prototype as well.
just incase someone thinks to suggest $content.cloneNode(true) that doesnt seem to pass prototype methods either. is there a way to reapply the prototype methods or better yet clone them with the element
here is the entire slert function
function genSlert(params) {
var slerts = getSlerts(),
$slert = document.createElement('div'),
$buttons = document.createElement('div'),
$ok = document.createElement('button'),
$cancel = document.createElement('button'),
$content = document.createElement('div');
for(var i = 0; i < slerts.length; i++){
slideUp(slerts[i]);
}
$buttons.className = 'buttons';
$content.innerHTML = params.content;
$content.className = 'content';
$slert.className = 'slert';
$slert.appendChild($content);
$slert.appendChild($buttons);
$buttons.appendChild($cancel);
$buttons.appendChild($ok);
$ok.innerHTML = 'OK';
$cancel.innerHTML = 'CANCEL';
wrapper.appendChild($slert);
wrapper.classList.remove('hidden');
document.body.classList.add('no-scroll');
$cancel.onclick = function (e) {
if (params.cancel) {
params.cancel(e);
}
//close modal
closeSlert($slert);
}
$ok.onclick = function(e){
if(params.ok){
var $cont = $content.cloneNode(true);
params.ok($cont);
}
closeSlert($slert);
}
}

Change zIndex using javascript

It works on the premade divs but on the newly made one, it doesn't work. How do I fix that?
Here's the code on the event for changing the zIndex:
$(".widget").mousedown(function (event) {
var ws = document.getElementById("widget-workspace");
var list = ws.children, x=0;
for(x=0;x<ws.children.length;x++){
console.log(ws.children[x].id);
$("#"+ws.children[x].id).css("zIndex", 99);
}
$(this).css("zIndex", 100);
});
Now, here's the code for adding the div:
document.getElementById("widget-dialog-button").onclick = function () {
var ws = document.getElementById("widget-workspace");
var list = ws.children;
var x, w = document.getElementById("select-widget");
var widget = w.options[w.selectedIndex].value;
var c = document.getElementById("select-widget-color");
var color = c.options[c.selectedIndex].value;
var left = 0, top = 25, docWidth = ws.offsetWidth, check;
for(x=0; x < list.length; x++){
docWidth -= 325;
left += 325;
if(docWidth < 325){
check = false;
docWidth = ws.offsetWidth;
left = 0;
top += 210;
}else{
check = true;
}
}
x-=2;
var iDiv = document.createElement('div');
iDiv.id = 'widget_'+x;
iDiv.className = 'widget';
iDiv.style.backgroundColor = color;
iDiv.style.left = left;
iDiv.style.top = top;
ws.appendChild(iDiv);
$(function() {
$( ".widget" ).draggable();
});
};
If you guys need anything else, feel free to ask.
The answer is quite simple :
"It works on the premade divs but on the newly made one, it doesn't work. How do I fix that?"
It's normal :
$(".widget").mousedown(...);
// should be read as (except that a new var is not created)
var $currentlyExistingWidgets = $(".widget");
$currentlyExistingWidgets.mousedown(...);
To each element of class widget currently existing, you bind an event.
If you want to bind events to elements not existing... You have to reconider your way of thinking and then bind an event listener to a container always existing, with an event delegation mechanism and proper filtering.
For example the following code should catch the event for all .widget, created before or after :
// http://api.jquery.com/on/
$('body').on('mousedown', '.widget', function() { ... });
If you want to search and learn, the key concepts are event bubbling and event delegation.
The way you're attaching the mousedown listener means that only the element that exist at that point will be listened to. Use the on method:
// May want to use something other than body
$('body').on('mousedown', '.widget', function() {
console.log('go');
});
Docs

Javascript - strikethrough

i try to make text strikethrough with javascript.
I know nothing about Javascript and try to search on the net how to that.
<script language="JavaScript">
function recal(val,sum)
{
if(sum == true)
{
var total = parseInt(document.getElementById("total").innerHTML, 10);
total+=val;
document.getElementById("total").innerHTML=total;
}
else
{
var total = parseInt(document.getElementById("total").innerHTML, 10);
total-=val;
document.getElementById("total").innerHTML=total;
var pnl = document.getElementById("totalEvents");
}
var pnl = document.getElementById("totalEvents");
var pnl2 = document.getElementById("eventCategory");
var pnl3 = document.getElementById("nameID");
**strikethrough starts here**
if (!sum && pnl.firstChild.tagName != "S" && pnl2.firstChild.tagname !="S")
{
pnl.innerHTML = "<S>"+ pnl.innerHTML+"</S>";
pnl2.innerHTML = "<S>"+ pnl2.innerHTML+"</S>";
}
else
{
pnl.innerHTML = pnl.firstChild.innerHTML;
pnl2.innerHTML = pnl2.firstChild.innerHTML;
}
}
</script>
it makes textstrikethrough but something is wrong. Even if i choose second checkbox it affects first checkbox why :(
http://jsfiddle.net/aHH9w/ (my full html page)
You are peforming a pretty convoluted way of achieving this, something that can actually be quite easily done. If you have an HTML element, say with the id 'myelement':
<div id="myelement">Hello world</div>
To create a strikethrough, all you need to do in JS is:
var ele = document.getElementById("myelement");
ele.style.setProperty("text-decoration", "line-through");
If you need to check if there is a strikethrough on an element:
var ele = document.getElementById("myelement");
var isStruck = (ele.style.getProperty("text-decoration") == "line-through");
Although this is not really recommended. Use an internal variable to keep track of state.

Find an anchor in a Div with javascript

In javascript I have a reference to a div. In that div is an anchor element with a name='foundItem'
How do I get a reference to the anchor with the name foundItem which is in the Div I have the reference of?
There are 'many' foundItem anchors in other divs on the page. I need 'this' DIVs one.
// assuming you're not using jquery or mootools
// assume div is mydiv
var lst = mydiv.getElementsByTagName('a');
var myanchor;
for(var i=0; i<lst.length; ++i) {
if(lst[i].name && lst[i].name == 'foundItem') {
myanchor = lst[i];
break;
}
}
// the mootools method
var myanchor = $(mydiv).getElement('a[name=foundItem]');
You can use the getElementsByTagName method to get the anchor elements in the div, then look for the one with the correct name attribute:
var found = null;
var e = divReference.getElementsByTagName('A');
for (var i=0; i < e.length; i++) {
if (e[i].name && e[i].name == 'foundItem') {
found = e[i];
break;
}
}
If found is not null, you got the element.
If you happen to use the jQuery library, you can let it do the searching:
var found = null;
var e = $(divReference).find('a[name=foundItem]');
if (e.length == 1) found = e.get(0);
Use a JavaScript library like jQuery and save yourself time.
var theAnchor = $('#divId a[name=foundItem]');
Using jquery, it's dead easy:
<script type="text/javascript">
$(function(){
var item = $("#yourDivId a[name=foundItem]")
)};
</script>
Update:
As per the comments, if you have control over what to id/name/class your anchor tag/s, it would be best to apply a class to them:
<div id="firstDiv">
test
</div>
<div id="secondDiv">
test another one
</div>
<!-- and so forth -->
<script type="text/javascript">
$(function(){
var item = $("#firstDiv a.foundItem");
alert(item.html()); // Will result in "test"
var item2 = $("#secondDiv a.foundItem");
alert(item2.html()); // Will show "test another one"
)};
</script>
If you're doing anything with javascript, jQuery saves you tons of time and is worth investing the effort to learn well. Start with http://api.jquery.com/browser/ to get an intro to what's possible.
Not sure if this helps, but wanted a function to handle the load of a page dynamically and scroll to the anchor of choice.
function scrollToAnchor(anchor_val) {
alert("" + anchor_val);
var page = document.getElementById('tables');
var found = null;
var cnt = 0;
var e = document.getElementsByTagName('a');
for (var i = 0; i < e.length; i++) {
if (e[i].name && e[i].name == anchor_val) {
found = e[i];
break;
}
cnt++;
}
if (found) {
var nPos = found.offsetTop;
alert("" + nPos);
page.scrollBy(0, nPos);
} else {
alert('Failed with call of scrollToAnchor()' + cnt);
}
}

Categories

Resources