I created a small script that counts images that I uploaded/inserted to my html source code. After I inserted images script creates div containers for those images. If I gave three images, then script will create three divs with class name etc. I have css rule with that class name. This was create before any images were in that container. Everything works but I just can't append those newly images to newly created divs. Is there a way using JavaScript only?
Here is a code:
if (document.getElementsByClassName("Multimedia")[0].getElementsByTagName("IMG")) {
total_number_of_images = document.getElementsByClassName("Multimedia")[0].getElementsByTagName("IMG").length;
for (i = 0; i < total_number_of_images; i = i + 1) {
document.getElementsByTagName("IMG")[i].className = "Image_clip";
child = document.getElementsByTagName("IMG")[i];
image_container = document.createElement("DIV");
image_container.className = "Image_container_div";
document.getElementsByClassName("Multimedia")[0].appendChild(image_container);
document.getElementsByTagName("IMG")[i].style.opacity = "0.8";
}
}
I tried somthenig like this:
image_container.appendChild(child);
But then I can get only two images into container... my third is out and also without className. Without this code, I get className for every image
You should cache the reference to elements rather than querying DOM in loops.
If I understood correctly, Your code should look something like the following for wrapping each image in a container <div>:
var container = document.getElementsByClassName("multimedia")[0];
// if there is only one match, use an id instead ------------^ ?
var images = container.getElementsByTagName("img");
for (var i = 0; i < images.length; i++) {
var img = images[i];
img.className = "imageClip";
img.style.opacity = "0.8"; // Why not define this in imageClip class ..?
imageContainer = document.createElement("div");
imageContainer.className = "imageContainer";
imageContainer.appendChild(img);
container.appendChild(imageContainer);
}
This I get on Yahoo answer. Posted by YaYox: http://jsfiddle.net/ffxad4bq/4
function myFunction() {
var multimedia = document.getElementsByClassName("Multimedia")[0]
var imgs = multimedia.getElementsByTagName("IMG");
for (var i = 0; i < imgs.length; i++) {
imgs[0].className = "Image_clip";
imgs[0].style.opacity = "0.3";
multimedia.innerHTML += '<div class="Image_container_div">'+imgs[0].outerHTML+'</div>';
imgs[0].remove()
}
}
I realized what was the problem. I shouldn't itaret through images. Just leave it on zero because, when loops start, code append one image at a time. When second loop starts I don't have any more 3 images, but two, that is why one image always stays out because loop goes three times.
Related
I have these sections on this side scrolling site. And want to add a class which will change styling depending if you're on a certain section.
I'm working on this function. The top is what determines the section of the side scroller you are viewing.
The let variables and below is where it stops working. I'm trying to have it so if a nonHome ID section is clicked, for example "slide-1", then add the class 'nav-visibilty'. If they are a match "slide-2" and "slide-2" then remove said class. Am I close?
https://codepen.io/mikayp-the-styleful/pen/NWPxoXR?editors=1111
setTimeout(function(){
for (i=0; i < nonHome.length; i++ ){
if (nonHome[i].id != nonHomeID){
nonHome[i].classList.add("nav-visibility");
console.log('add')
} else{
nonHomeID.classList.remove("nav-visibility");
console.log('rem')
}
}
I am still not totally clear on the behavior that you want, but there are two errors in the code that can be fixed:
It seems like you are always using 'slide-2' instead of the slideId in your event handler.
As mentioned in a comment, nonHomeID is being used incorrectly in your comparison (it is either a string or an element, but you are using it as if it was a string in the if condition, and as the element in the else branch.) Here I have kept it as an element and renamed it for clarity.
Fixing these errors results in code that applies the nav-visibility class to all slides except the one selected by the button. Is that the desired behavior?
let nonHome = document.querySelectorAll(".slide-container section");
let nonHomeSelected = document.getElementById(slideId);
var i;
setTimeout(function() {
for (i = 0; i < nonHome.length; i++) {
if (nonHome[i] != nonHomeSelected) {
nonHome[i].classList.add("nav-visibility");
console.log("add");
} else {
nonHome[i].classList.remove("nav-visibility");
console.log("rem");
}
}
}, 1000);
Edit to add: If the goal is to add nav-visibility to all only the specific slideId, you should not be adding in a loop, i.e. you need to pull your check for whether the slide is Home outside the loop. There are conceptually two steps here: remove the class from all elements that are no longer to have it, then add the class to the element that needs it.
let slideToAddVisibilityTo = document.getElementById(slideId)
let homeSlide = document.getElementById('slide-2')
let allSlides = document.querySelectorAll(".slide-container section")
for (let i = 0; i < allSlides.length; ++i)
allSlides[i].classList.remove('nav-visiblity')
if (slideToAddVisibilityTo != homeSlide)
slideToAddVisibilityTo.classList.add('nav-visibility')
Just hide them all, then show the clicked one:
function showSection(id) {
var sections = document.getElementsByTagName("section");
for(var i=0; i<sections.length; i++) sections[i].classList.remove("nav-visibility");
var current = document.getElementById(id);
current.classList.add("nav-visibility");
}
Example: showSection("foo") will remove nav-visibility from all sections, then add it to the section with id foo.
I wrote a script in a section of my HTML code to output an image to my browser 10 times by using a for loop. This works fine, but I also want to write a script in the head element of the markup where I can maybe use a function to first create an HTMLCollection from the image elements, and then loop through all ten images in the collection, adding 5 pixels to the width and height properties of each succeeding image element from left to right when any one of the ten images is clicked.
I've tried to research information on HTMLCollections combined with DOM related properties and other equations, but have been unsuccessful so far.
Script from the body element
<section>
<h2>Growing Pumpkins</h2>
<p id="smashingPumpkins" onclick="growingPumpkins(this)" ></p>
<script>
for (var i = 0; i < 10; i++) {
document.getElementById("smashingPumpkins").innerHTML += "<img src='bandit.png' />";
}
</script>
</section>
Script from the head element:
<script>
function growingPumpkins(img) {
var img = document.images;
for (index in img) {
document.getElementById("smashingPumpkins").innerHTML = img[index].style.width + 1.05;
document.getElementById("smashingPumpkins").innerHTML = img[index].style.height + 1.05;
}
}
</script>
The size of each image should increase by 5 pixels spanning from left to right (apologies for the redundancy) when output to the browser. However, I have been unable to accomplish this, and only see the number 1.05 when I click on one of the images.
What about this?
for (var i = 0; i < 10; i++) {
document.getElementById("smashingPumpkins").innerHTML +=
`<img src='bandit.png' style="width:${base + i*5}px; height:${base + i*5}px "/>`;
}
Of course the 'base' being used in the style attribute is something you set, like 100 or however many pixels you want the height and width of the first one to be
EDIT:
That was just to make each picture bigger than the last, which is not exactly what you asked. But your comment makes me think I should leave it for learning purposes. What you could do have each picture expand on click, and each one expand 10px bigger than the one before it, is this:
Add a class to your images to easy targeting, then target them into an array:
for (var i = 0; i < 10; i++) {
document.getElementById("smashingPumpkins").innerHTML +=
"<img src='bandit.png' class="expandingImg" />";
}
var images = document.querySelectorAll('.expandingImg') // creates an array of your image elements
Now loop through your array of elements and attach an event listener to each one. The event listener will change the style element of that element, based on the element's position in the array. So elements later in the array will expand more than ones earlier in the array. This also eliminates the need for your onclick="growingPumpkins(this)" because the eventlisteners are being added in this immediately invoked functional expression (IIFE):
(function growingPumpkins() {
for (let i = 0; i < images.length; i++) {
images.addEventListener('click', function(){
images[i].style = `style="width:${base + i*5}px; height:${base + i*5}px`
}, false)
})()
I think that should do it. You'll need to add another event listener so that they shrink back down to their original size, like mouseleave or something like that. Hopefully this works and is helpful.
Using JavaScript, how to identify all images?
A straightforward approach is to traverse all DOM elements, and check: 1) if it is an <img />; 2) if its style includes background-image.
To get all img elements
var allImgs = document.getElementsByTagName('img');
To check if any element has a background-image, I might try something like this:
if (element.style['background-image'] != null) {/* your code */}
I'm not entirely sure about the 2nd one.
Get all images on the page:
function img_tag_find()
{
var img_collect = document.getElementsByTagName('img'); //collection of image
var img_collect_massiv = []; //array for image
for (var i = 0; i < img_collect.length; i++)
{
img_collect_massiv.push(img_collect[i].src); // push next image
}
return img_collect_massiv; // return array of image
}
Get element with style = 'background-image' - can be offered as Ramdas Nair
if (element.style['background-image'] != null) {/* your code */}
or try so (through all the elements, but not sure what's right do not have time to check)
function find_backgroundImage()
{
var object = document.getElementsByTagName('body');
var img_collect_massiv = []; //array for element page
for (var childItem in object.childNodes)
if (object.childNodes[childItem].style['background-image'] != null)
img_collect_massiv.push(object.childNodes[childItem]);
return img_collect_massiv; // return all element with style = 'background-image'
}
For cases when background image is defined in CCS, check whether an HTML element has a background image or not this way:
window.getComputedStyle(htmlElement).backgroundImage
The best way to gather all background images on a page would be to walk through all of active CSS to gather all of background-image references along with the style tag/class names to which the corresponding background images apply. Then only select HTML elements that match the corresponding styles all while making sure that they are not collapsed/hidden/display-none'd.
Hi I have got a jsFiddle to share but never used it before so I hope I did it right..
http://jsfiddle.net/Mayron/3V62C/
I also have these screen shot to better show what I mean:
http://i.imgur.com/NgQk5P2.jpg
I have a table of images in the gallery page and when you click on an image it opens up a frame that shows a blank but much larger image which gains the source of the smaller image you clicked on. That works fine but I have all the images in the gallery listed in an array and the large frame has three buttons on it: previous, close and next. So far the JavaScript code allows you to click next and previous to go through them but it always begins the journey from array[0] and that is no good if you click to view the 6th one in the list from the gallery page first for example.
I hope that makes sense if not then let me know!
The issue is with this line that causes it to begin from the first image:
currentIndex = 0;
How can I change this so that the currentIndex number is the image that the user first clicks on?
There are several ways but that really depends on what you use and how clean you want your code to look. I put a hidden input in each of my divs and retrieve it with JQuery's $("input", $(this).parent()).val();
You could also use Jquery's index. http://api.jquery.com/index/
You could have it in a class and retrieve the class of the clicked item (same idea as having an ID for each image)
On click you can have a selector added in the class attribute then you can use a for-each to count how many images go through before you hit that class in your image order.
You could also do showLarge(this, index#) and set the index that way. I cannot get your JS fiddle to work though.
Do this for every image line:
<td><a href="#" onclick="javaScript:showLarge(this,1);" ><img class="imgBorder" id="image1" src="Media//Gallery//img_1.jpg" alt="Gallery Image 1" /></a>
</td>
This puts onclick in anchor tag and adds an id in the image tag named image1 (1 is the number you put in the anchor tag 2nd param)
In javascript, do:
function showLarge(img, index) {
var largeFrame = document.getElementById("zoomedIn");
largeFrame.style.visibility = 'visible';
var largeImage = document.getElementById("largeImage");
src = document.getElementById("image"+index);
largeImage.src = src.src;
currentImage = index;
}
This gets the image by id according to index clicked
For the next+prev button do:
function changeImage(direction) {
index = parseInt(currentIndex) + parseInt(direction);
if (index < 1) {
index = 1; // or use imgArray.length to rotate round
}
if (index > imgArray.length) {
index = imgArray.length; // or use 0 to rotate round
}
src = document.getElementById("image"+index);
document.getElementById('largeImage').src = src.src;
currentIndex = index;
}
Try something like this:
function findIndex(src) {
for (i = 0; i = imgArray.length; i++)
if (imgArray[i].src == src) {
currentIndex = i;
return;
}
}
function showLarge(img) {
var largeFrame = document.getElementById("zoomedIn");
largeFrame.style.visibility = 'visible';
var largeImage = document.getElementById("largeImage");
largeImage.src = img.src;
findIndex(img.src);
}
It will update the currentIndex value.
I've updated your jsfiddle: http://jsfiddle.net/RN4bN/
But I can't run it, so try directly on your code.
Put an ID on each of them which is the number of it from the array, then when it is clicked change the currentIndex to that.
I have created function for creating a div, when u selet the value in dropdown box , based upon the length the number of divs will be created , so the code is
<select onchange="test()" id="selected_opt">
<option value="0" selected>-Select-</option>
<option value="1">Communication</option>
<option value="2">XXXXXXXXXXXXX</option>
</select>
the function test is
function test(){
var result = get_id.options[get_id.selectedIndex].value;
if(result == 1){
var i = 0,
c = model_details_json.communication,
j = c.length,
communications_div = document.getElementById("model_communication");
if(j == 0){
alert('nothing');
}
for (; i<j; i++){
var communication = c[i];
var create_div = document.createElement('div');
create_div.id = 'communication_id'+i;
create_div.name = 'communication';
var create_anchor = document.createElement('a');
create_anchor.innerHTML = communication.communication_name;
communications_div.appendChild(create_div);
document.getElementById(create_div.id).appendChild(create_anchor);
create_anchor.setAttribute("href", "javascript:void(0);");
create_anchor.setAttribute("onclick","sample('"+communication.communication_name+"','"+create_div.name+"')");
}
}
for example the length is 6 means the six number of divs will be created , so what the problem is when i again click on communication in select dropdown i.e already the six divs have been created , when do it again then agin six divs are created , so totally 12 divs created when u do it again it goes for 6 multiples.......
so what i need is the number of div would not be repeated. and it should be validate whether the user is clicking the same value in dropdown
Check this to remove div elements considering your parent div model_communication.
You need to implement logic by checking if the div exist and stop the loop when you get a message like 'Div is already removed' as shown in the example.
In order to do so create div elements along with id
var newdiv = document.createElement('div');
newdiv.setAttribute('id', id);
You need to remove all divs before create the new ones. Try adding a class name to it:
var create_div = document.createElement('div');
create_div.className = 'communication_div';
...
Now you can select the divs. Before the for statement add these lines to remove the divs with 'communication_div' class name:
var divs = document.getElementsByClassName('communication_div');
for(var i=0; i<divs.length; i++) {
divs[i].parentNode.removeChild(divs[i]);
}
Every script run will generate new divs and remove old ones.
use js map object to put selected value or length as key into the map then everytime user clicks a value, first check for its existence in the map. If not found in the map, that would mean length is not repeating and divs will be created.
something like:
var selectedValues = new Array();
.......
var result = get_id.options[get_id.selectedIndex].value;
if(selectedValues["val_"+result]) {
return;
}
selectedValues["val_"+result] = true;
you can check if the div is already created or present on page using getElementById('elementId') before creating it.
like in you code
for (; i<j; i++){
if(! document.getElementById('communication_id'+i)){ // do if element is not present on page
var communication = c[i];
var create_div = document.createElement('div');
create_div.id = 'communication_id'+i;
create_div.name = 'communication';
var create_anchor = document.createElement('a');
create_anchor.innerHTML = communication.communication_name;
communications_div.appendChild(create_div);
document.getElementById(create_div.id).appendChild(create_anchor);
create_anchor.setAttribute("href", "javascript:void(0);");
create_anchor.setAttribute("onclick",
"sample('"+communication.communication_name+"','"+create_div.name+"')");
}
}
Use replaceChild() instead of appendChild() on the Element object.