Replace Images by their alt-text using javascript - javascript

I found out so far how to replace element by another element on a html-page. But my function is working in a strange way. First it replaces first and third image. If i invoke it again, it replaces only the second image. Pressing button again makes finally the last fourth image replace. Somebody any ideas about that? Here's the source: http://pastie.org/5502630
And here you can see how it works: http://clubnights.square7.ch/webtech/a2.html

With each pass through the for loop, you remove the first image from the images[] array. This changes both the array contents and the array length set as the conditional in your loop.
For example, your first loop through removes images[0], ausdruck_1.gif -- but now images.length equals 3, not 4, and the contents of the array are now:
images[0]=ausdruck_2.gif
images[1]=ausdruck_3.gif
images[2]=ausdurck_4.gif
Your second pass through the loop removes images[1] -- now ausdruck_3.gif -- and further changes the length of the images array to 2, so the next increment of i to 2 causes the loop to exit.
I created a jsfiddle showing a possible solution of changing your for statement to:
for(i = images.length-1; i >=0; i--)
and looping through the images in reverse order.

You're modifying the list of images as you're iterating through it. So when you try to access the images array it's not what you think it is! Below is a possible workaround..
function Convert()
{
images = window.document.getElementsByTagName('img');
var num_images = images.length;
for (var i = 0; i < num_images; i++)
{
var image = images[0];
textReplacement = document.createTextNode(image.getAttribute('alt'));
image.parentNode.replaceChild(textReplacement, image);
}
}

Related

Setting id attribute in javascript prevents function from running properly

I am trying to make a memory game and I want to give each image an ID so that the program can keep track of which images are the same. My function was working properly and generating the grid of random images but when I try to give the images their respective ID, random images just come out missing. Does anyone have an idea why this is happening?
function placeImages(arr){
let place = 0;
let num = 0;
let box = 1;
for(let i = 0; i < 10; i++){
num = arr[place];
const pic = document.createElement('img');
pic.id = `${num}`; //THIS IS THE PROBLEM
// pic.setAttribute('id', `${num}`); //number pics
pic.classList.toggle('pic');
pic.setAttribute('src', `./images/${num}.png`);
document.getElementById(`${box}`).appendChild(pic); //goes box by box and add image
box++;
place++;
}
console.log(arr);
}
The array is a random array of 10 numbers 1-5 only repeating once like {1, 3 , 2, 5, 5, 3, 2, 1, 4, 4}
The first image is with "pic.id = ${num};" commented out and the second one it is not commented out. I just started learning so sorry if the code is hard to understand.
result without id
result with id
So what I think this comes down to is that the ID attribute should be completely unique to each HTML element on a page. However, your code has multiple IDs that are the same. In the image you posted that was not displaying images it was where it was trying to give you one element with the ID of ${box} on line12. You expect this to be your div to place an image but instead, it probably got an image element that you created in a previous iteration of the loop. That is my guess and I hope that helps.
Take away: Keep IDs unique to every HTML Element!
What I recommend doing is something like this:
pic.id = `pic-${num}-${i}`;
Which will do something like this:
<img src="4.png" id="pic-4-2">
This way every ID will be unique because images will be prefixed with "pic" and postfixed with the iteration number. Then later in your code, you can splice out the middle number to match them to another image.

Using shift() brings back the first one every time (javascript)

I have a function that searches for every time ; is found inside a textarea and makes it into a array. See the code below.
function compile() {
// Sets the variable for every line
var compileLineCount = document.getElementById('devInput').value.split(';');
for (let i = 0; i < compileLineCount.length; i++) {
console.log(document.getElementById('devInput').value.split(';').shift(i))
console.log(i)
}
}
But whenever I call the function, it shows the first one every time.
Anyone know how to fix this? Help would be very appreciated.
As per the official shift() document.
The shift() method removes the first element from an array and returns that removed element. This method changes the length of the array.
Hence, It should be like :
var compileLineCount = document.getElementById('devInput').innerHTML.split(';');
for (let i = 0; i <= compileLineCount.length; i++) {
const splittedValue = compileLineCount.shift(i)
console.log(splittedValue)
console.log(i)
}
<p id="devInput">
Hello my name is alpha;Age is 30;I love to help
</p>
I figured out what I did wrong. I forgot shift() also removes the item from the array.
I changed it from .shift(i) to [i].
Thank you jsn00b for the link to the docs
Your shift() method is used incorrectly. According to MDN, it states:
The shift() method removes the first element from an array and returns that removed element.
So, the shift() method doesn't take any parameters. This is why your code isn't working.
To fix this issue, you can get the index from the array using [i], like so.
document.getElementById("devInput").value.split(";")[i];
The only difference in that line is that .shift() is replaced with [i], which gets the element in the array at that specific index.

Filled Array with unique Elements - How can i copy it so i get every order possible?

This is my first question here, I think the answer will be a small piece of Code.
Lets say i have a filled array at any lenght with unique elements:
let a = [A,B,C]
My question is,
How can I process the array, so that I have a list or x arrays , that show every possible order for these elements of the array above
like:
A,B,C
A,C,B
B,A,C
B,C,A
C,B,A
C,A,B
I dont really have an idea and tried to look in the web so far.
Thanks for the answers!
The recursive idea is:
function order(list, ans){
let size = list.length;
if(size == 0){
console.log(ans);
return;
}
for(var i = 0; i < size; i++){
let first = list.shift();
order(list, ans + `${first},`);
list.push(first);
}
}
Basically, for each element, you set it as a first and recursively do the same thing with the rest of the list.

How to use splice method to solve my problem correctly?

I am displaying rotating images.
var pics= [
"images/img1.jpg",
"images/img2.jpg",
"images/img3.jpg",
];
And would want it to stop onClick.
function StopRotate(interval, imgIndex) {
clearInterval(interval);
var permanentImage = picture[imgIndex].src;
picture[imgIndex].src = permanentImage;
pics.splice(pics.indexOf(picture[imgIndex].src), 1);
}
Here's how I rotate the images (this block has three occurrences for three image containers):
interval0 = setInterval(function () {
if(pics.length != 1) {
picture[0].src = pics[count];
count++;
if (count == pics.length) count = 0;
}
else picture[0].src = pics[0];
}, 10);
But the image occurs yet again to other frames even if the path has been already removed from the array. I tried this using 12 images. Some times when I run it, the src turns out to be undefined.
Also if I click the images unordered, the images from other frames becomes blank. In this sample, I have three images, if I clicked on the third container, the first container becomes blank, how does that affect other frames when the interval functions are separate. There's no problem however when clicking it in order. Note I have changed the sequence where I put the if condition inside setInterval.
The .src property will return a fully qualified pathname which will never be found in your array of partial path names when you try to look for it with .indexOf().
You can use .getAttribute("src") to get what is actually in the HTML and that should then match what you have in your array.
Example: http://jsfiddle.net/jfriend00/3H8XF/

Trouble Replacing Multiple Links With iFrame Via Javascript

I'm trying to parse a page with javascript to replace links belonging to a specific class with an iframe to open a corresponding wikipedia page [so that rather than having a link you have an embedded result]. The function detects links properly but something about the replaceChild() action causes it to skip the next instance... as if it does the first replace and then thinks the next link is the one it just worked on, probably as a result of the loop.
For example, if there's 2 links on the page, the first will parse and the second will not even be seen but if there's 3, the first two will be parsed using the attributes from the first and third.
Can anyone suggest an alternative way of looping through the links that doesn't rely on a count function? Perhaps adding them to an array?
Sample Links
wiki it
Sample Javascript
(function(){
var lnks = document.getElementsByTagName("a");
for (var i = 0; i < lnks.length; i++) {
lnk = lnks[i]; if(lnk.className == "myspeciallinks"){
newif=document.createElement("iframe");
newif.setAttribute("src",'http://www.wikipedia.com');
newif.style.width="500px";
newif.style.height="100px";
newif.style.border="none";
newif.setAttribute("allowtransparency","true");
lnk.parentNode.replaceChild(newif,lnk);
}
}
})();
The problem here is that document.getElementsByTagName returns a NodeList and not an array. A NodeList is still connected to the actual DOM, you cannot safely iterate over its entries and at the same time remove the entries from the DOM (as you do when you replace the links).
You will need to convert the NodeList into an array and use the array for iteration:
(function(){
var lnksNodeList = document.getElementsByTagName("a");
// create an array from the above NodeList and use for iteration:
var lnks = Array.prototype.slice.call(lnksNodeList);
for (var i = 0; i < lnks.length; i++) {
var lnk = lnks[i];
if (lnk.className == "myspeciallinks") {
var newif = document.createElement("iframe");
newif.setAttribute("src", 'http://www.wikipedia.com');
newif.style.width = "500px";
newif.style.height = "100px";
newif.style.border = "none";
newif.setAttribute("allowtransparency", "true");
lnk.parentNode.replaceChild(newif, lnk);
}
}
})();
According to the MDN documentation:
Returns a list of elements with the given tag name. The subtree underneath the specified element is searched, excluding the element itself. The returned list is live, meaning that it updates itself with the DOM tree automatically. Consequently, there is no need to call several times element.getElementsByTagName with the same element and arguments.
Therefore, the collection shrinks every time you replace an a. You could change your loop to decrement i whenever you do a replace.

Categories