Relative images broken, need javascript fix - javascript

new here. I have no access to most of the source files on my website, so I am trying to fix some broken images on page load with javascript.
When I use the inspect element for one of these broken images it shows like this:
<img src="-82.jpg" width="60px">
when they should be
<img src="http://example.com/files/images/-82.jpg" width="60px">
This is for bunch of different images, -82.jpg, -2482.jpg, -3582.jpg
Here's what I have tried so far. This seems to work but for some reason it breaks other javascript on the page.
html
<script type="text/javascript" src="http://example.com/files/js/fiximages.js"></script>
<body onload="fixImages();">
my fiximages.js file
function fixImages() {
var toReplace = '<img src="-';
var replaceWith ='<img src="http://www.example.com/files/images/-';
document.body.innerHTML = document.body.innerHTML.replace(toReplace, replaceWith);
}
I'm a bit of a noob so I also need to know how to link the html to the javascript to get it to load when the page loads. Thanks guys.

This should solve your problem:
function fixImages() {
// Create a list of all img which src starts with "-".
var imgs = document.querySelectorAll('img[src^="-"]');
// Loop through this list.
for (var i = 0; i < imgs.length; i++) {
// For each img, replace its src with the correct path + the
// src that's already there.
imgs[i].setAttribute('src', 'http://www.example.com/files/images/' + imgs[i].getAttribute('src'));
}
}
Demo

Welcome to SO!
The problem in your approach is that changing the body's pure HTML is never a good idea for a dynamic page. Also, javascript's replace, when used without a regex, is going to replace only the first ocurrence of the string.
Now, when you need to change an element's attribute, Javascript has a manipulation called DOM. There are plenty material and tutorials on the web... You should look into it!
http://www.w3.org/TR/DOM-Level-2-Core/introduction.html
http://www.w3schools.com/jsref/dom_obj_document.asp
With DOM, you can select an element as a variable, and manipulate its properties and attributes, so, in your case it would be:
function fixImages() {
var imgs = document.getElementsByTagName("img");
for(var i=0; i<imgs.length; i++) {
if(imgs[i].src.indexOf("-") == 0)
imgs[i].src = "http://www.example.com/files/images/" + imgs[i].src;
}
}

Related

How can I select a generated title tag with jQuery?

I'm working on a SVG map (Raphael) on a Drupal site, and for some reason beyond me I can't get jQuery to affect the SVG map at all. I want to manipulate the <a> and its child (a path) using the title="skane" value as an anchor.
One weird thing is that when looking at the generated Raphael code in the inspector it says title="skane", but if i copy the entire block to jsFiddle I get xlink:title="skane" – what's up with that?
In a Fiddle it seems to be working just fine using $("a[xlink\\:title=skane]").hide(); but when I try to incorporate it into my script it doesn't do anything, even when entered in the console well after page load.
If I target all <a> tags with $('a').hide(); the whole map disappears as expected, so how do I select only the <a> with title="skane"?
Link to jsFiddle example
Any help is greatly appreciated!
Have you tried $("a[title='skane']").hide();?
I found this solution. However I am not sure if that´s what you need.
var parameters = document.getElementsByTagName("a");
for (var i = 0; i < parameters.length; i++) {
var attribs = parameters[i].attributes;
for (var j = 0; j < attribs.length; j++) {
if (attribs[j].localName == "xlink:title" && attribs[j].value == "skane") {
parameters[i].style.display='none';
}
}
}
Hope it Helps

Apply Mathjax to arbitrary elements

I have emacs org-generated HTML that contains dvipng'd equations by default. That's ok, I want to provide a good fallback for those who disabled their JS. The generated pictures and resulting <img> tags have complete LaTeX source in their alt attribute. I have also tweaked the code to apply a specific class to all such images so it becomes a simpler matter in JS end, which isn't my forté.
The MathJax documentation lists a couple of different configurations and a way to customize a configuration by myself; I don't see a selector function or anything to apply Mathjax to suit my needs. I know I can write own DOM-munging JS and then call Mathjax afterwards but surely Mathjax bends to this kind of functionality by itself?
This is an example from the generated HTML.
<img class="dvipng" src="upload/blog_ff4e604.png"
alt="$\frac{1}{2\pi{}i}\int_C\frac{f'(z)}{f(z)}{\rm d}z = N_0(f)$">
MathJax doesn't include this directly, but you could do the following:
<script type="text/x-mathjax-config">
MathJax.Extension.myImg2jax = {
version: "1.0",
PreProcess: function (element) {
var images = element.getElementsByTagName("img");
for (var i = images.length - 1; i >= 0; i--) {
var img = images[i];
if (img.className === "dvipng") {
var script = document.createElement("script"); script.type = "math/tex";
var match = img.alt.match(/^(\$\$?)(.*)\1/);
if (match[1] === "$$") {script.type += ";mode=display"}
MathJax.HTML.setScript(script,match[2]);
img.parentNode.replaceChild(script,img);
}
}
}
};
MathJax.Hub.Register.PreProcessor(["PreProcess",MathJax.Extension.myImg2jax]);
</script>
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML"></script>
which defines a new preprocessor that looks for your images and extracts the math from the ALT tags. This assumes you use $...$ for in-line math and $$...$$ for displayed math.
This code removed the image when it converts it to the MathJax <script> tag. It would be possible to move the image to a preview span where it will show up until MathJax processes the TeX code. That is a bit more sophisticated, but could be done with a little more work. I'll leave that to the interested reader. :-)

remove image element based on source

How can I use vanilla javascript + regEx to remove image elements, based on their source?
I am reading a RSS feed with a web app. I want to remove certain image elements if their source contains the word "comments".
It would be ideal to edit the rss feed before it's rendered onto the page (just pulled from the http request, and still in a 'string').
update:
Thanks for the replies. At the very bottom of each article, they are including a link to comments... which is what I want to remove.
Here is the code at the very end of each article:
<a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ADDRESS/FEED"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/[ADDRESS]/[FEED]" /></a>
also, the [feed] value changes per article. So would it be better to check for the word 'comments' or check if the source starts with x?
var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
var img = images[i];
if (img.src.indexOf('comments') > 0) {
var link = img.parentNode;
link.parentNode.removeChild(link);
}
}
line 1: get a list of all images elements on the page
line 2: iterate over the list, remove those who's src has the word 'comments'. This is done by calling the indexOf method of any string object. Detailed here
Thanks for the replies. lins05 suggested some code that i've adjusted slightly. Note: instead of removing the element or it's parent, the following code simply hides the element.
var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
var img = images[i];
if (img.src.indexOf('comments') > 0) {
img.style.display = "none";
}
}
The rss feed's list of articles are stored in a model on the page. It would be more ideal to chop the comments out of the model.. however the current approach of 'hiding the element every time the article is on the page' works fine :)
You may try this
var imgs=document.images;
for(i=0;i<imgs.length;i++)
if(imgs[i].src.test('comments'))
imgs[i].parentNode.parentNode.removeChild(imgs[i].parentNode);​
DEMO.

document.write() and Ajax - Doesn't work, looking for an alternative

I recently asked a question here, and received a great response (which I will shortly be accepting the most active answer of, barring better alternatives arise) but unfortunately it seems the of the two options suggested, neither will be compatible with Ajax (or any dynamically added content that includes such "inline-relative jQuery")
Anyways, my question pertains to good ole' document.write().
While a page is still rendering, it works great; not so much when an appended snippet contains it. Are there any alternatives that won't destroy the existing page content, yet still append a string inline, as in where the call is occurring?
In other words, is there a way/alternative to document.write() that when called post-render, doesn't destroy existing page content? An Ajax friendly version so to speak?
This is where I'm going:
var _inline_relative_index = 0;
function $_inlineRelative(){
// i hate non-dedicated string concatenation operators
var inline_relative_id = ('_inline_relative_{index}').replace('{index}', (++_inline_relative_index).toString());
document.write(('<br id="{id}" />').replace('{id}', inline_relative_id));
return $(document.getElementById(inline_relative_id)).remove().prev('script');
}
And then:
<div>
<script type="text/javascript">
(function($script){
// the container <div> background is now red.
$script.parent().css({ 'background-color': '#f00' });
})($_inlineRelative());
</script>
</div>
you have access to the innerHTML property of each DOM node. If you set it straight out you might destroy elements, but if you append more HTML to it, it'll preserve the existing HTML.
document.body.innerHTML += '<div id="foo">bar baz</div>';
There are all sorts of nuances to the sledgehammer that is innerHTML, so I highly recommend using a library such as jQuery to normalize everything for you.
You can assign id to the script tag and replace it with the new node.
<p>Foo</p>
<script type="text/javascript" id="placeholder">
var newElement = document.createElement('div');
newElement.id='bar';
var oldElement = document.getElementById('placeholder');
oldElement.parentNode.replaceChild(newElement, oldElement);
</script>
<p>Baz</p>
And if you need to insert html from string, than you can do it like so:
var div = document.createElement('div');
div.innerHTML = '<div id="bar"></div>';
var placeholder = document.getElementById('placeholder'),
container = placeholder.parentNode,
elems = div.childNodes,
el;
while (el = elems[0]) {
div.removeChild(el);
container.insertBefore(el, placeholder);
}
container.removeChild(placeholder);

How can I apply a function to several images in jQuery?

I need a little help with (probably) something really simple.
I want to use a script which converts images from color to grayscale.
I got it working partially — the first image turns gray, but the second won’t.
I know this is because an id cannot be used multiple times:
var imgObj = document.getElementById('grayimage');
I tried this:
var imgObj = $(’.grayimage’)[0];
But it didn’t work. Changing it to getElementByClass also does not work. (Before people ask, I did change the id to class in the <img> tag.)
I really could use some help here. Thanks in advance!
$('.grayimage').each(function(idx,imgObj){
<do your code here>
});
$('.grayimage') gives you a list of all elements with grayimage as a class. If you add '[0]' you're accessing the first element, so any changes you make will apply to only the first image that it finds with this class.
You should loop through all elements:
var images = $('.grayimage');
for(i = 0; i < images.length; i++) {
var image = images[i];
// Do stuff
}

Categories