I'm using plain Javascript in a 3d art gallery. I have an image source array and am populating certain columns by pulling from this array. I need to get the index of the image on click so that I can use that to pull further information from said array...Titles, Descriptions.
I could do this with jQuery but I am trying to learn plain Javascript. I already have event listeners on all the images. Here is the current code:
var preview = document.getElementById('preview');
var subwrap = document.getElementById('subwrap');
var indexMatch;
for (var i=0; i <= imgList.length; i++){
document.images[i].addEventListener("click", srcSend, false);
}
function srcSend(){
var previewTitle = "Test Title";
var previewText = "Test Description";
var imgSrc = this.src;
console.log('Image Source ='+''+imgSrc+'');
if (imgSrc !== "file:///D:/Projects/mpaccione/img/navicon.png"){
preview.className = " ";
subwrap.className = "hide";
preview.className = "show";
preview.innerHTML = '<img src='+imgSrc+'><p id="title">'+previewTitle+'</p><p id="description">'+previewText+'</p>'; }}
You should be able to use the Array.indexOf on the images collection.
function srcSend(){
var index = Array.prototype.indexOf.call(document.images, this);
}
You can send the index to the srcSend function.
for (var i=0; i <= imgList.length; i++){
document.images[i].addEventListener("click", function(){
return (function(index) {
srcSend(index);
})(i);
}, false);
}
Related
2 Questions:
What will be the most officiant way to loop through all of the Images on a given page and open each one in a new tab.
Same idea but instead open in a new tab I would like to push different images instead of the given ones. The idea is to build a widget that will inject cat photos instead of the normal photos of websites.
I answered 2 in the code, and 1 in the comment of the first code block
var allImages = document.getElementsByTagName('img');
for(var i = 0; i < allImages.length ; i++) {
// to open all photos in new tabs:
// window.open(allImages[i].src, '_blank');
allImages[i].src = 'url_to_cat_image';
}
you can also do the same with jquery:
// change all photos to the same one:
var allImages = $('img');
allImages.attr('src', 'url_to_cat_image');
If you want each photo to be a different image, just replace the url_to_cat_image with a function that returns a random cat image in the first code block. For jquery, you can use .each and a random cat url function.
Here's a way of doing it with vanilla js. As mentioned in the comments, using the document.images node-list is the best method for getting the images, since it's a static list and need not be assembled in response to dom queries.
As mentioned, browsers will block the attempts to open new windowss, labelling them as pop-ups.
Here's a demo:
function forEachNode(nodeList, func) {
for (var i = 0, n = nodeList.length; i < n; i++) func(nodeList[i], i, nodeList);
}
function onBtnClicked() {
var diskUrl =
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC" +
"3RAAABdElEQVQoU22SLX/CMBCH/3E4IueorKNysh+hH6ESR93mqBuOuuEWiYyczB" +
"zycJPBIa+uU9nvmlD2wonmLulz78q+c4DIMH7Hk0UfOJ5/75KtrOWg9RxEwHqdfr" +
"xz9F9AXX9Ag8fXG3jssX6a3yUFwtCjqgnsDbK8gjIHDtnDHM6dsdks/oFXSNKuVg" +
"5VXoA+HZQxHLJsDvt+xu7lN/gTYgbqxqHMM3hPUGbvQ5YvYO0Ju91yivgX4oETWI" +
"AvBNV1PhTFAuZwwttrBO9B0u2qkVSzBG4jKL2yhxNYtDSSmx5HM0LyxgTVthEUkT" +
"qY+2mO0cHVUZrrOF8P1T5TKIpl8tTDHdvfnZ0BeqbBXN6WYiCoRsB8OUUiamEPHY" +
"qyhNlbYAZ0+w6eirRFUpSHapoIeu5Hj/TZwV8I5WOFZlUn0MA5DS3lANCSarOikE" +
"nRzDBHAi4dum1MV1IcI25beK6mvdUgKLHqlQsCSsRJpAlXIzUomvH+G/9qC1CEZi" +
"AJAAAAAElFTkSuQmCC";
forEachNode(document.images, function(elem) {
elem.oldSrc = elem.src;
console.log(elem.src);
window.open(elem.src);
elem.src = diskUrl
});
}
function onResetBtn() {
forEachNode(document.images, function(elem) {
if (elem.oldSrc != undefined) elem.src = elem.oldSrc;
});
}
<button onclick='onBtnClicked()'>Open pop-ups, change image sources</button>
<button onclick='onResetBtn();'>Reset</button>
<br>
<img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAHCAYAAAAvZezQAAAAKElEQVQIW2MUder+/3pfKSMDFDCCBEBsmCBcACaIIgASxK0CxQxkWwA6axnpT9J3PwAAAABJRU5ErkJggg==' />
<img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAHCAYAAAAvZezQAAAAJElEQVQIW2NkQAKiTt3/GWF8EAfEBgvAOGABZA52FVjNQBYEAPsjDS+SFXnjAAAAAElFTkSuQmCC' />
This is how you loop through all the images in a page.
I've also added example of opening in a new tab or replacing the source.
using native JavaScript no dependencies required.
// Array of cat photos
var arr = ['cat1.jpg', 'cat2.jpg', 'cat3.jpg'....]
var elem = document.getElementsByTagName('img');
for (var i = 0; i < elem.length; i++) {
var src = elem[i].getAttribute('src');
// Open in a new tab
if (src) window.open(src);
// Replace with a random cat photo
elem[i].src = arr[Math.floor(Math.random() * arr.length)];
}
Using vanilla javascript :
var images = document.querySelectorAll("img");
for(var i = 0;i < images.length;i++){
var image = images[i];
window.open(image.src,"_blank");
}
// changing for a kitty image
var images = document.querySelectorAll("img");
for(var i = 0;i < images.length;i++){
var image = images[i];
image.src = "http://placekitten.com/600/338";
}
However, if there are more than 1 image the browser will prevent that (see the popup message and allow that behaviour).
I'm really new to javascript from C# and i'm having a little trouble. I wrote this function to make adding menu's a bit easier on my site. It works well except I can't seem to give my div's an individual url, even though I can give them an individual innerHtml.
I've been stuck trying different things such as divs[i].location.url etc.. but I can't seem to have anything work. My current solution has each div link to /contact.html which I'm a little confused by.
function DrawMainMenu() {
var btns = [
["About", "/about.html"],
["Portfolio", "/portfolio.html"],
["Resume", "/resume.html"],
["Contact", "/contact.html"]
];
var numOfBtns = btns.length;
var divs = new Array(numOfBtns);
for (var i = 0; i < numOfBtns; i++) {
divs[i] = document.createElement("div");
divs[i].className = "menuBtn";
divs[i].innerHTML = btns[i][0];
divs[i].style.height = (30 / numOfBtns) + "%";
divs[i].style.lineHeight = 3.5;
var link = btns[i][1];
divs[i].addEventListener('click', function() {
location.href = link;
}, false);
document.getElementById("buttons").appendChild(divs[i]);
}
}
Thanks
The problem is that the variable link gets overwritten each iteration, so when the event handler it gets link, which is the string '/contact.html', since that was the last value given to it.
You can try setting onclick attribute to elements, which will store the variable in the attribute onclick. Therefore, it will have the old and correct value.
function DrawMainMenu() {
var btns = [
["About", "/about.html"],
["Portfolio", "/portfolio.html"],
["Resume", "/resume.html"],
["Contact", "/contact.html"]
];
var numOfBtns = btns.length;
var divs = new Array(numOfBtns);
for (var i = 0; i < numOfBtns; i++) {
divs[i] = document.createElement("div");
divs[i].className = "menuBtn";
divs[i].innerHTML = btns[i][0];
divs[i].style.height = (30 / numOfBtns) + "%";
divs[i].style.lineHeight = 3.5;
var link = btns[i][1];
divs[i].setAttribute('onclick', 'location.href = "' + link + '"');
document.getElementById("buttons").appendChild(divs[i]);
}
}
DrawMainMenu();
<div id="buttons"><div>
Updated answer
Here we make use of closures. Using a closure (closing the values of link) we bind the value to the scope of the click handler.
function DrawMainMenu() {
var btns = [
["About", "/about.html"],
["Portfolio", "/portfolio.html"],
["Resume", "/resume.html"],
["Contact", "/contact.html"]
];
var numOfBtns = btns.length;
var divs = new Array(numOfBtns);
for (var i = 0; i < numOfBtns; i++) {
(function() {
divs[i] = document.createElement("div");
divs[i].className = "menuBtn";
divs[i].innerHTML = btns[i][0];
divs[i].style.height = (30 / numOfBtns) + "%";
divs[i].style.lineHeight = 3.5;
var link = btns[i][1];
document.getElementById("buttons").appendChild(divs[i]);
divs[i].addEventListener('click', function() {
location.href = link;
}, false);
}());
}
}
DrawMainMenu();
<div id="buttons"><div>
I have to fetch data from the PHP web service in an array and then display it on HTML page using JavaScript. I have used a for loop to do so. But it doesn’t render proper output. Due to innerHTML the output gets replaced. Please help with your suggestions. Here is my code:
function jsondata(data){
alert("JSONdata");
var parsedata = JSON.parse(JSON.stringify(data));
var main_category = parsedata["main Category"];
for (var i = 0; i <= main_category.length; i++) {
menu = JSON.parse(JSON.stringify(main_category[i]));
menu_id[i] = menu['mcatid'];
menu_title[i] = menu['mcattitle'];
menu_img[i] = menu['mcatimage'];
pop_array.push(menu_id[i], menu_title[i], menu_img[i]);
//alert(pop_array);
for (var i = 0; i < main_category.length; i++) {
alert("for start");
var category = document.createElement("li");
document.getElementById("mylist").appendChild(category);
//document.getElementById("mylist").innerHTML='<table><tr><td>'+pop_array[i]+'</td></tr></table>';
document.write(pop_array.join("<br></br>"));
alert("for end");
}
}
}
Although I don't get why pop_array was used here but I assume that you are trying to display the category info as a li tag.
You should set category.innerHTML instead of document.getElementById("mylist").innerHTML.
function jsondata(data){
var parsedata = JSON.parse(JSON.stringify(data));
var main_category = parsedata["main Category"];
for (var i = 0; i < main_category.length; i++) {
var menu = main_category[i];
var category = document.createElement("li");
category.innerHTML = menu['mcattitle']; // construct your own html here
document.getElementById("mylist").appendChild(category);
}
}
Following the documentation sample, I'm trying to create a function that searchs for a numerated list in a google document and, if finds it, adds a new item to that list. But I get this error: Cannot find method setListId(string). (line 21, file "test") or, if I change line 21 content (replacing elementContentfor newElement), I get the message: Preparing for execution... and nothing happens. How to fix it?
This is my code:
function test() {
var elementContent = "New item testing"; // a paragraph with its formating
var targetDocId = "1R2c3vo9oOOjjlDR_n5L6Tf9yb-luzt4IxpHwwZoTeLE";
var targetDoc = DocumentApp.openById(targetDocId);
var body = targetDoc.getBody();
for (var i = 0; i < targetDoc.getNumChildren(); i++) {
var child = targetDoc.getChild(i);
if (child.getType() == DocumentApp.ElementType.LIST_ITEM){
var listId = child.getListId();
var newElement = body.appendListItem(elementContent);
newElement.setListId(newElement);
Logger.log("child = " + child);
}
}
}
Following my comment, I tried to play with your script to see what happened and I came up with that code below...
I'm not saying it solves your issue and/or is the best way to achieve what you want but at least it gives a result that works as expected.
Please consider it as a "new playground" and keep experimenting on it to make it better ;-)
function test() {
var elementContent = "New item testing"; // a paragraph with its formating
var targetDocId = DocumentApp.getActiveDocument().getId();
var targetDoc = DocumentApp.openById(targetDocId);
var body = targetDoc.getBody();
var childIndex = 0;
for (var i = 0; i < targetDoc.getNumChildren(); i++) {
var child = targetDoc.getChild(i);
if (child.getType() == DocumentApp.ElementType.LIST_ITEM){
while(child.getType() == DocumentApp.ElementType.LIST_ITEM){
child = targetDoc.getChild(i)
childIndex = body.getChildIndex(child);
Logger.log(childIndex)
i++
}
child = targetDoc.getChild(i-2)
var listId = child.getListId();
Logger.log(childIndex)
var newElement = child.getParent().insertListItem(childIndex, elementContent);
newElement.setListId(child);
break;
}
}
}
Alright, I have been looking off and on for almost a year now (spent all of March trying to do this), and I simply CAN NOT find the code to make this work.
Here's my problem:
I have a code that retrieves my most recent upload for the player on my website (http://weapwn.com). This code only gives me the video, though.
I need code to get the description - not from any one video ID, but from the variable video ID - but all I have is this:
<script type="text/javascript">
function showMyVideos2(data) {
var feed = data.feed;
var entries = feed.entry || [];
var html = ['<ul>'];
for (var i = 0; i < entries.length; i++) {
var entry = entries[i];
var content = entry.content.$t;
html.push('<i>', content, '</i>');
}
html.push('</ul>');
document.getElementById('featdesc').innerHTML = html.join('');
}
</script>
Now - replacing "content" does nothing, unless I use "title" (which only retrieves the video title). I must know how to get this damn elusive code to work, because the parameters that Youtube lists are not working!
Am I going about this entirely the wrong way? Or is there simply an error to fix in my code?
Try this:
function showMyVideos2(data) {
var feed = data.feed;
var entries = feed.entry || [];
var html = ['<ul>'];
for (var i = 0; i < entries.length; i++) {
var entry = entries[i];
var title = entry.title.$t;
var description = entry.media$group.media$description.$t.replace(/\n/g, '<br/>');
var content = entry.content.$t;
html.push('<i>', content, '</i>','<i>', title, '</i>','<i>', description, '</i>');
}
html.push('</ul>');
document.getElementById('featdesc').innerHTML = html.join('');
}
Hope it helps...