Access and remove dynamically created element - javascript

I've used a for loop to create a bunch of images with unique ids. They look something like this:
<img src="image.jpg" id="110021002" />
<img src="image.jpg" id="110021003" />
<img src="image.jpg" id="110031002" />
...
Later on in the code I want to select one of the images by ID and remove it. I tried the following:
var removeId = '110021002';
var img = document.getElementById(removeId);
img.parentNode.removeChild(img);
But I get the following error:
Cannot read property 'parentNode' of null
Not quite sure what's going on here. Is it because the images were created dynamically?

Your code works perfect: http://jsbin.com/zexoweyu/3/edit for the first time you remove an element, obvisouly on the second attempt the element is not there and it will throw the given error.
On the fiddle:
Click once, works
Click again, fails because the element with that ID is no longer there.
And yes, ids can start with numbers.
**Attribute ID** Specifies a unique id for the element. Naming rules:
Must contain at least one character
Must not contain any space characters
In HTML, all values are case-insensitive

You can't have IDs that start with a number. Try prefixing them with a letter.

Related

Change image source depending of its ID

The title already tell's a little bit. I'm getting a list of documents with links and images like this:
<img class="Thumbnail" src="sourcetothepdfimage.png" id="/path/pdf.png"/>
The only two things that may differ are src and id. What I try to reach now is to replace the image src depending on its ID. The ID may be /path/pdf.png or /path/word.png or something completely different (which I don't know yet).
What would be the recommended way to achieve this? I have three different images for the replacement (one for PDF, one for word files and one generic for all other unknown file types).
I think document.getElementByID doesn't make that much sense because I only know two fix IDs. With this I can change the src for PDF and DOCX but not for any other, right?
So document.getElementsByClassName would be the targeted solution, but how can I iterate through all five or more listed elements with the class "Thumbnail"?
I'm barely new to the Dev world and like to learn it.
It's simple using jQuery.
// get all img's using class selector
// and use `attr()` method with callback which iterate internally
// within the callback return the id( within callback this refers to the current element DOM object)
$('.Thumbnail').attr('src',function(){
return this.id
})
<img class="Thumbnail" src="sourcetothepdfimage.png" id="/path/pdf.png"/>
Try (no jquery)
[...document.querySelectorAll('.Thumbnail')].map(img=> img.src=img.id);
console.log([...document.querySelectorAll('img')]);
<img class="Thumbnail" src="sourcetothepdfimage.png" id="/path/pdf.png"/>
<img class="Thumbnail" src="sourcetothesomimage.png" id="/path/pdf2.png"/>
<img class="Thumbnail" src="sourcetothedocimage.png" id="/path/doc.docx"/>

How do I click this link using nightmare?

Here is everything involving the link:
<a class="" data-images="{"detail_url":"//assets.supremenewyork.com/148393/ma/hBwFmRXhVKI.jpg","zoomed_url":"//assets.supremenewyork.com/148393/zo/hBwFmRXhVKI.jpg"}" data-style-name="Black" data-style-id="19033" data-sold-out="false" data-description="null" href="/shop/bags/lkav6jh17/xfdbgpiea" data-no-tubolink="data-no-tubolink"><img width="32" height="32" src="//d17ol771963kd3.cloudfront.net/148393/sw/hBwFmRXhVKI.jpg" alt="Hbwfmrxhvki"></a>
I use nightmare with node coded in atom and would like to click on the black bookbag from the url: http://www.supremenewyork.com/shop/bags/lkav6jh17/p9ylgt8vm
using the "data-style-name="Black" found in the elements.
I've tried:
.click("data-style-name ='Black'")
which gave me the error:
Failed to execute 'querySelector' on 'Document': 'data-style-name ='Black'' is not a valid selector.
Not sure what to do to click but any help would be great. The link is an image and part of a list element on the webpage.
first grab the DOM node and assign to a variable then click on the node. Also you need to add brackets around the selector and don't need the inner single quotes unless there is a space or other invalid character in the value
var myLink = document.querySelector("[data-style-name=black]");
.click(myLink)
Also what I did was:
.click('a[data-style-name="Tan"]')
I specified it was an attribute and it worked.

not able to change class within id although no errors

I don't understand why my extraInfo variable isn't being printed out onto the webpage.
The information is being retrieved correctly (I've tested this with alert()) but I just cannot figure out why it isn't replacing the span text with the returned value.
I've tried sending it out wrapped in P tags too and although no errors come out, it still doesn't amend the text.
https://github.com/ralam87/Quote-generator
Where am I going wrong?
document.getElementById("source").getElementsByClassName("citation")[0] = extraInfo;
I gone through your example.
Note: when you are trying to assign the citation to first element with .citation class that time the there are no elements present with the class citation because it get replaced when you set the value to source element just before citation document.getElementById("source").innerHTML = author;.
This are possible solution
change this document.getElementById("source").getElementsByClassName("citation")[0] = extraInfo; to document.getElementsByClassName("citation")[0].innerHtml = extraInfo;
remove the id from <p id="source">
create another <span> or <div> or <p> element inside the existing <p> and assign the id=source to that inner element. for example <p><span id="source"></span><span id="citation"></span></p>.
If you want to have the , after the source name then at the time of assigning the document.getElementById("source").innerHTML = author + ',';.
If you allow me i can also contribute this directly to you git
repository.

Using regexp to match pattern not in img tag

I want to do an online chatting application, its sending emoji ability like this:
So I use an div whose contentEditable is true as input area. And all of the message would be saved in database in this way:
"Hello, Cathy<img src="/public/face/Mazes_Mini_017.png"><img src="/public/face/Mazes_Mini_017.png">"
All of these above works well, but at that time I want to do a search ability, highlighting the key word I search, I met a problem when I want to use string.replace method to replace myKeyWord with <span class='highlight'>myKeyWord<span>, but it would match some characters in <img> tag...
eg. <img src="/public/face/Mazes_Mini_017.png">112233test112233</img>123test123
keyword is test
expected result is:
<img src="test.png">112233test112233</img>123test123
So I really want to use regExp to matched some characters not in a specify tag like <img>, I have tried a lot but no one worked...
Here is an example
You could try this: (?<!<\/)test(?![^<]*<\/img>)

JavaScript repair bad html tag

I'm working on a Sharepoint website. I don't have access to the webparts code. I can only change master pages with JavaScript.
One of the webpart has a bug. It changes the <img> with a bad SRC value.
example:
should have
<img alt="img" src="http://www.apicture.png" style="margin:5px" /><br /><br />
but have
<img alt="img" src="http://www.apicture.png" style="margin:5px" /><br /><br />
I tried to match and replace but the innerHtml broke the others scripts.
How can a repair my with JavaScript ?
Edit:
I have the code:
var markup = document.documentElement.innerHTML;
markup = markup.replace(/src=\".*?(http:\/\/[^\"]+)\"/g,'src=\"$1\"');
document.documentElement.innerHTML = markup;
but it broke my webpage.
Since the DOM has already been broken, you need to take a step back and try to salvage the HTML.
1) Find the parents of the broken elements. While search&replace inside the document.body.innerHTML would probably work, you shouldn't really let regexes anywhere near large chunks of HTML. Performance is a concern as well, albeit a lesser one.
<img alt="img" src="<a href="http://... will get parsed by the browser as an image with the source "<a href=".
With jQuery, you can simply ask $('img[src="<a href"]') to get the images. Except in IE<8, you can use querySelectorAll with the same selector. If you don't have jQuery, and want to support IE7, you need to use getElementsByTagName with manual filtering.
If you are really lucky, you can find the parent via getElementByID (or the equivalent jQuery).
This is the easy part.
2) Your HTML doesn't validate, and the browser had already made some effort to fix it. You need to reverse the process. Predicting the browser actions is problematic, but let's attempt to.
Let's see what the browser does with
<img src="http://www.test.com/img/image-20x20.png" style="margin:5px" />​
This is how Chrome and Firefox fix it:
<img src="<a href=" http:="" www.test.com="" img="" image-20x20.png"="">http://www.test.com/img/image-20x20.png" style="margin:5px" />
IE9 sorts the attributes within img alphabetically in innerHTML (o_0) and doesn't HTML-escape the < within src. IE7-8 additionally strip ="" from the attributes.
The image attributes will be hard to salvage, but the text content is unharmed. Anyways the pattern can be seen:
everything starting at <img and until src= should be preserved. Unfortunately, in IE, the arguments are rearranged, so you have to preserve the incorrect tags as well. src="..." itself must be removed. Everything past that is [incorrect] in modern browsers, but in IE, proper attributes could have crept there (and vice versa). Then the image tag ends.
Everything that follows is the real URL, up until the double quote. From the double quote up until the HTML-escaped /> are attributes that belong to the image tag. Let's hope they don't contain HTML. CSS is fine (for our purposes).
3) Let's build the regex: an opening IMG tag, any attributes (let's hope they don't contain HTML) (captured), the src attribute and its specific value (escaped or unescaped), any other attributes (captured), the end of tag, the URL (captured), some more attributes (captured) and the HTML-escaped closing tag.
/<img([^>]*?)src="(?:<|\&lt\;)a href="([^>]*?)>([^"]+?)"(.*?)\/>/gi
You might be interested in how it's seen by RegexPal.com.
What it should be replaced by: The image with the proper attributes concatenated, and with the src salvaged. It might be worthy to filter the attributes, so let's opt for a callback-replace. Normal attributes contain only word-characters in their keys. More importantly, normal attributes are usually non-empty strings (IMG tags don't have boolean attributes, unless you are using server-side maps). This will match all empty attributes but not valid attribute keys: /\S+(?:="")?(?!=)/
Here is the code:
//forEach, indexOf, map need shimming in IE<9
//querySelectorAll cannot be reliably shimmed, so I'm not using that.
//author: Jan Dvorak
// https://stackoverflow.com/a/14157761/499214
var images = document.getElementsByTagName("img");
var parents = [];
[].forEach.call(images, function(i){
if(
/(?:<|\&lt\;)a href=/.test(i.getAttribute("src"))
&& !~parents.indexOf(i.parentNode)
){
parents.push(i.parentNode)
}
})
var re = /<img([^>]*?)src="(?:<|\&lt\;)a href="([^>]*?)>([^"]+?)"(.*?)\/>/gi;
parents.forEach(function(p){
p.innerHTML = p.innerHTML.replace(
re,
function(match, attr1, attr2, url, attr3){
var attrs = [attr1, attr2, attr3].map(function(a){
return a.replace(/\S+(?:="")?(?!=)/g,"");
}).join(" ");
return '<img '+attrs+' src="'+url+'" />';
}
);
});
fiddle: http://jsfiddle.net/G2yj3/1/
You can repair src attribute with regex but it won't repair the entire page. The reason is that web browser is trying to parse such bad HTML and produces weird output (extra elements etc.) before JS is executed. Since you cannot interfere the HTML parsing/rendering engine, there's no reasonable way other than changing the original content to fix this.

Categories