I'm trying to use window.location.pathname and injecting innerHTML to generate the file paths for an image so all I need to do is type fileName.png in a div in the html body and have the javascript generate the file path behind it so that it displays the image in the rendered website. This is for images that aren't stored in the same folder as the working file.
I've had mild success but it only works for one image per page which isn't very helpful.
I've gotten this code to work for one image per page:
<div class="picName">pic.png</div><div id=<"shortcut"></div>`
<script>
var relativePath = window.location.pathname;
var picName = document.getElementById('matts-shortcut').previousElementSibling.innerHTML;
document.getElementById("matts-shortcut").innerHTML =
'<src=\'/images' + relativePath + '/' + picName + '\'>';
</script>
The solution below pulls images names from with Divs using .querySelectorAll() which returns a DOM NodeList. The NodeList is useful because it has a forEach() method that can be used to loop over each item is the list. Loop over each list item using it's textContent property as the image name. Then you'll need to create a new image element for each image. To do that you can do something similar to this.
let relativePath = "https://dummyimage.com"; // replace the url with path name (maybe window.location.path)
// create a reference to the input list
// querySelectorAll return a NodeList
let inputNameList = document.querySelectorAll('.image-name');
// Loop through each image name and append it to the DOM
// the inputNameList (NodeList) has a "forEach" method for doing this
inputNameList.forEach((image) => {
let picName = image.textContent;
// Create a new image element
let imgEl = document.createElement('img');
// Set the src attribute of the image element to the constructed URL
// the name of the picture will be the div text content
// This is done with a template literal that you can learn about here:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
imgEl.src = `${relativePath}/${image.textContent}`;
// Now we have a real image element, but we need to place it into the DOM so it shows up
// Clear the image name
image.textContent = "";
// Place the image in the Div
image.appendChild(imgEl);
});
<div class="image-name">300.png</div>
<div class="image-name">200.png</div>
<div class="image-name">100.png</div>
<div class="image-name">400.png</div>
EDIT: In response to Ismael's criticism, I've edited the code slightly and commented every line so you can learn from this answer. There are two hyperlinks referenced in the code to help you think about coding in a modern way and so you can interpret modern code you read more easily.
About:
Arrow functions
Template Literals
Edit 2:
With further clarification, the answer has been amended to pull the image file names from Div elements already in the DOM.
Let ID equal your element's id
Call on:
document.getElementById(ID).src = "image_src"
When you want to change images, like an onclick action or as part of a function.
Related
I've gone through many SO threads, I can't seem to find a working solution.
All I'm trying to do is when the page loads, the site pushes all elements with the ".home" class into the array arr. Then, the script parses through each element in the array and tries to match it with a string. For example, right now all I have is a check to see if the element has the words "Boston" in it, in which case I want to make the image source for ".homeimage" the linked imgur link. I'm aware it's not wise to host images on imgur for these reasons, I'm just trying to check if it works. Below this test I have some redundant code I was practicing with that I found in a SO thread, changing the color of text to gray. I figured changing attributes is the same.
my html code:
<td colspan = "3"width=400px class = "home"><b><%= game.home %></b></td>
<td colspan = "3"><img style="width:150px;height:128px;" class = "homeimage"></td>
my javascript/jquery code:
<script>
var arr=[];
$(document).ready( function(){
$(".home").each(function(){ arr.push($(this));});
for(i = 0; i < arr.length; i++){
if(arr[i].indexOf "Boston" != -1){
$('.homeimage img').attr("src","http://i.imgur.com/s5WKBjy.png");
}
}
$.each(arr,function(key,val){
val.css('color','gray')}); //something redundant i was testing out
});
</script>
additional questions:
When I have multiple image with the .homeimage class, and multiple checks to determine the image source, will it make all of the images in the .homeimage class that src at the end? So whatever the last image that gets checked is the image src for all of the images with the ".homeimage" class? I don't want that. How can I uniquely make each image? Make a custom id instead of a class for each div? Also, does this script have to be below the html in question? Or does that not matter
Thanks for the future advice you all.
// I don't quite understand what you want to do.
// Since you type too much, and make no highlights.
// but here are somethings I found:
var arr = []; // this array is going to contain all tags (like td) with class '.home'
if(arr[i].innerHTML.indexOf("Boston") != -1) { } // indexOf() won't work on DOM element
// then arr[0] must be a DOM element, so why you call .indexOf("Boston") on it?
// next, $('.homeimage img') all return DOM element with class 'homeimage' or with tagName 'img'
$('img.homeimage'); // this may what you want to do.
// Alright, I try to give you an answer.
// this oImgUrl works as a map from some ((String))-->((img url))
var oImgUrl = {
'Boston': 'http://another.imageurl.com/boston.png',
'NewYork': 'http://another.imageurl.com/newyork.png'
};
// I take your "arr" unchanged
// this will test every element in arr
// if carry String like 'Boston' or 'NewYork'
// then find the img tag (img.homeimage) in it.
// then apply URL string to img tag
for (var i=0, length=arr.length; i < length; i++) {
if(arr[i].innerHTML.indexOf("Boston") != -1) {
arr[i].find('img.homeimage').attr('src', oImgUrl['Boston']);
continue;
}
if(arr[i].innerHTML.indexOf("New York") != -1) {
arr[i].find('img.homeimage').attr('src', oImgUrl['NewYork']);
continue;
}
}
example html:
<td class='home'>Welcome to Boston!<img class='homeimage'></td>
<td class='home'>Welcome to New York!<img class='homeimage'></td>
answers:
Question 1: Custom ID?
JavaScript will find these two td.home and add them into arr.
then, apply different image url to img tag
according to innerHTML of the td tag.
when doing this, you don't need to set each img tag an unique ID.
Question 2: Script place below html?
No, you don't have to.
You hold all thses script in docuement ready function
so, they will only work when HTML DOM is ready.
in another words, no matter where you place this script,
they will be invoked after Every Tag is ready.
Probably a simple question but I can't seem to find the answer. I am dynamically creating a page where I can share twitter links.
var twitter = document.createElement('a');
twitter.setAttribute('href', 'http://twitter.com/share');
twitter.setAttribute('class', 'twitter-share-button twitter-tweet');
twitter.setAttribute('data-text', 'I liked this image');
etc..
I then append it to the div I want such as
$('#doc').append('<img(miscellaneous HTML)>'+twitter)
What I have above works but for CSS formatting purposes I want the image with the twitter share button to be a sub-block. So I create something like this
$('#doc').append('<div id="innerblock'+i+'"><img(miscellaneous HTML)>'+twitter+'</div>)
But when I do this it seems all the attributes of the twitter var are lost, only printing http: // twitter.com/share on the page instead of the button.
I feel it's probably a basic concept I am forgetting.
You are tring to concatenate a DOM object and a String via this code
$('#doc').append('<div id="innerblock'+i+'"><img(miscellaneous HTML)>'+twitter+'</div>)
This twitter variable contains a DOM object and the rest of the append block is String.
Try this:
var div = $('<div id="innerblock'+i+'"><img(miscellaneous HTML)></div>').append(twitter);
$('#doc').append(div);
What I would do is instead of appending the HTML instead you can create the innerblock div and the img tags using document.createElement and append the twitter to the img and the img to the div before appending it all to #doc
You can not concatenate a sting and a DOM node.
var div = $("<div id="innerblock'+i+'">").append("<img />").append(twitter);
or
var div = $("<div/>", {id : "innerblock" + i).append("<img />").append(twitter);
Try substituting .outerHTML String of twitter for DOM element Object twitter ; also adding closing sing quote ' at end of string parameter provided to .append()
var twitter = document.createElement('a');
twitter.setAttribute('href', 'http://twitter.com/share');
twitter.setAttribute('class', 'twitter-share-button twitter-tweet');
twitter.setAttribute('data-text', 'I liked this image');
var i = 0;
$('#doc').append('<div id="innerblock'+i+'"><img />'+twitter.outerHTML+'link</div>')
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div id="doc"></div>
I have a site that has a banner at the top of the page. I've started to overhaul my HTML structure and am now getting various pieces of information that populate the site out of an XML file. My HTML that uses the jQuery is:
<script>
function myExampleSite()
{
var myURL = window.location.href;
var dashIndex = myURL.lastIndexOf("-");
var dotIndex = myURL.lastIndexOf(".");
var result = myURL.substring(dashIndex + 1, dotIndex);
return result;
}
var exampleSite = myExampleSite();
</script>
<script>
var root = null;
$(document).ready(function ()
{
$.get("Status_Pages.xml",
function (xml)
{
root = $(xml).find("site[name='" + exampleSite + "']");
result = $(root).find("headerImage");
$("td#headerImage").html($(result).text());
var imageSrc=$(root).find("headerImage").text();
$(".PageHeader img").attr("src",imageSrc);
result = $(root).find("version");
$("td#version").html($(result).text());
result = $(root).find("status");
$("td#status").html($(result).text());
result = $(root).find("networkNotes");
$("td#networkNotes").html($(result).text());
....etc etc
});
});
</script>
My XML file looks like this.
<sites>
<site name="Template">
<headerImage>images/template-header.png</headerImage>
<productVersion>[Version goes here]</productVersion>
<systemStatus color="green">Normal</systemStatus>
<networkNotes>System status is normal</networkNotes>
</site>
</sites>
I have several <site>s that all have their own data that will populate different areas of individual sites. I've ran into some snags though.
The first snag is how it currently obtains its header image:
html
<div class="container">
<div class "PageHeader"> <!-- Header image read from XML file -->
<img border="0" src=""/>
</div>
Right now it's hard-coded to be the template header image, but I need to make that generic and read the XML value for that site. So instead of being hard-coded as images/template-header.png it would read the XML value for the current site, which is still going to be the template header - but it won't for every page.
How can I read in the image string to populate my HTML so that each site has a different image depending on what's in the XML?
Edit: Edited code to match current issue. Currently, I just get a broken image, but I can still change it back to the hard-coded image URL (images/template-header.png) and it works.
As you already have the code that can extract the image URL information from the XML, which is
result = $(root).find("headerImage");
$("td#headerImage").html($(result).text());
It's now a matter of attaching that URL, to the image tag. We need to select the object, and then simply change it's src attribute. With jQuery this is actually pretty easy. It'll look something like
var root = $(xml).find("site[name='" + site + "']");
//get the image url from the xml
var imageSrc=$(root).find("headerImage").text()
//get all the images in class .PageHeader, and change the src
$(".PageHeader img").attr("src",imageSrc)
And it should work
Example
In conclusion, if you already have some values you want to put in HTML tags dynamically, it's pretty easy. There's .html("<b>bold</b>") for content, there's .attr("attrName","attrValue") for general attributes. .css("background","red") for changing CSS directly. There's also some class modifying stuff that would be useful in the future.
Given a html, I'd like to get first 100 characters of text (content without the markups)
I could create a jquery object with the html and use .text().
But the problem is that browsers may load all the images in the html.
So I wonder if there's a way to extract text snippet from html without building a DOM.
edit
given a html (just a string of html, not part of DOM yet)
<p>my lord</p><img src="some_url"><br>I'm overloaded
I could do $('<div/>').append(html).text().substr(0, 5); to get 5 characters.
But the img is downloaded by browser, and I don't want that.
var s = "<p>my lord</p><img src=\"some_url\"><br>I'm overloaded"
s = s.replace(/<[^>]+>/g,'').substr(0, 100);
You could remove the image elements and then load it to the dom
Something like
var html = "<p>my lord</p><img src="some_url"><br>I'm overloaded";
html = html.replace(/<img[^>]*>/g,"");
var firstFive = $('<div/>').append(html).text().substr(0, 5);
I'm trying to create a JavaScript where you write a message and the time and message appears on the website. The function doing this is "renderMessage". However, it includes an image you can click to delete that message and then I want to write all the remaining ones again. Problem is that I don't know how to save some sort of ID so I know which image was clicked so I delete the correct position in the array of messages.
The code for renderMessage is:
function renderMessage(theMessage, theMessages){
var text = document.createTextNode(theMessage.getText());
var time = document.createTextNode(theMessage.getDate());
var div = document.getElementById("writeMessages");
div.appendChild(text);
div.appendChild(time);
var image = document.createElement('img');
image.src = 'img/deletePic.png';
div.appendChild(image);
div.appendChild(document.createElement('br'));
image.onclick = function(e){
theMessages.splice(); // This is where I don't know how to remove the correct one
removeAll(theMessages); // This removes all html code in the div and writes
// the array again (hopefully this time with the correct
// element removed from it)
};
}
Firstly, thumbs up for using plain js.
I would say you enclose the message, time and the image into another element. My be a ul li block. And, when you render the messages in DOM, you set the message id as id attribute of the li so it will be something like this
<ul>
<li>Message 1 - 10:21 PM <img src="remove jpg"/></li>
<li>Message 2 - 10:22 PM <img src="remove jpg"/></li>
</ul>
and your js code can be,
image.onclick = function () {
var message_id = this.parentNode.id;
// here you got the message id.
// splice your message array and render
}
Why are you re-rendering all the messages? You could simply
// splice your message array and render
var li = this.parentNode;
li.parentNode.removeChild(li);
}
you can save the id of the message inside an attribute of the element. eg <div class="your_message_container data-id="14">...</div>
Using jquery for example you can read that attribute with $(your_selector).attr("data-id"); and write it with $(your_selector).attr("data-id", "new_value");
As an alternative, also have a look at http://api.jquery.com/jquery.data/
Edit:
i made you a fiddle with pure js: http://jsfiddle.net/A64zh/2/ Note that the id of the message element must equal the data-message-id attribute of your delete image.
the advantage of using an element attribute for storing the id is that your javascript does not depend on the html structure like it does if you are using something like this.parentNode.parentNode.removeChild.... which would need to be changed if you would add more html layers in between the two