Cannot get rid of focus on element after double-click - javascript

I have a HTML5 web page and I use 4 canvas controls to render images from my web cam.
By double-clicking and image/canvas I hide the 4 canvases and display a larger canvas control instead.
As soon as I done this one of my controls is highlighted.
This is the original web page BEFORE the double-click:
And this is the web page AFTER the double click:
This is the code that handles the double-click of the smaller canvas element:
$('#canvasLiveView1').on('dblclick', function () {
$('#divSingleView').css('display', '');
$('#divMultiView').css('display', 'none');
camDoubleClickCam = 1;
});
I have tried adding this to the double-click event:
$('#btnPlaysave').blur();
where 'btnPlaySave' is ID of the highlighted control.
Incidentally, this behavior/effect does not appear in IE.
Any suggestions?
ND.
this is the HTML for the canavs 'toggle'
<div style="height:362px;">
<div id="divSingleView" style="float:left;margin:0px;padding:0px;background-color:black;width:520px;display:none;">
<div style="float:left;width:95px;"> </div>
<div style="float:left;width:330px;margin-top:75px;"><canvas id="canvasLiveView" style="width:330px;height:220px;outline: yellow 1px solid;"></canvas></div>
<div style="float:left;width:95px;"></div>
</div>
<div id="divMultiView" style="float:left;margin:0px;padding:0px;background-color:black;width:520px;">
<div style="float:left;height:170px;margin-left:2px; margin-top:10px;"><canvas id="canvasLiveView1" style="width:255px;height:170px;outline: grey 1px ridge;margin-left:3px;margin-top:3px;"></canvas></div>
<div style="float:left;height:170px;margin-top:10px;"><canvas id="canvasLiveView2" style="width:255px;height:170px;outline: grey 1px ridge;margin-right:3px;margin-top:3px;"></canvas></div>
<div style="float:left;height:170px;margin-left:2px; margin-bottom:10px;"><canvas id="canvasLiveView3" style="width:255px;height:170px;outline: grey 1px ridge;margin-left:3px;margin-top:3px;margin-bottom:3px;"></canvas></div>
<div style="float:left;height:170px;margin-bottom:10px;"><canvas id="canvasLiveView4" style="width:255px;height:170px;outline: grey 1px ridge;margin-right:3px;margin-top:3px;margin-bottom:3px;"></canvas></div>
</div>
</div>
<div style="height:30px;">
<div id="divPaused" style="display:none; float:left;margin-left:5px;color:white;font-size:9pt; font-weight:800;">
Paused
</div>
<div style="width:290px;margin: 0 auto;">
<div style="float:left;width:24px;margin-left:5px;">
<img id="btnPlaySave" alt="" style="width:24px;width:24px; cursor:pointer;" src="/Content/Images/save.png" class="imgPlaySave" title="Save Image" onclick="PlaySave();" />
</div>
<div style="float:left;width:24px;margin-left:5px;">
<img alt="" style="width:24px;width:24px; cursor:pointer;" src="/Content/Images/button_minus_red.png" class="imgPlaySlower" title="Decrease Playback Speed" onclick="PlaySlower();" />
</div>
<div style="float:left;width:24px;">
<img alt="" style="width:24px;width:24px; cursor:pointer;" cursor:pointer" src="/Content/Images/button_plus_green.png" class="imgPlayFaster" title="Decrease Playback Speed" onclick="PlayFaster();" />
</div>
<div style="float:left;width:24px;">
<img alt="" style="width:24px;width:24px; cursor:pointer;" src="/Content/Images/media_start.png" class="imgPlayStart" title="Go to First Frame" onclick="PlayStart();" />
</div>
<div style="float:left;width:24px;">
<img alt="" style="width:24px;width:24px; cursor:pointer;" src="/Content/Images/media_back.png" class="imgPlayStepBack" title="Step to Previous Frame" onclick="PlayStepBack();" />
</div>
<div id="Tempo" style="float: left; width: 40px; text-align: center; vertical-align: middle; font-weight: bold;color:white; font-size: x-small; font-family: Arial, Helvetica, sans-serif;">
100
</div>
<div style="float:left;width:24px;">
<img alt="" style="width:24px;width:24px; cursor:pointer;" src="/Content/Images/media_pause.png" class="imgPlayPause" title="Pause" onclick="PlayPause();" />
</div>
<div style="float:left;width:24px;">
<img alt="" style="width:24px;width:24px; cursor:pointer;" src="/Content/Images/media_play.png" class=" imgPlayPlay" title="Play" onclick="PlayPlay();" />
</div>
<div style="float:left;width:24px;">
<img alt="" style="width:24px;width:24px; cursor:pointer;" src="/Content/Images/media_next.png" class="imgPlayStepNext" title="Step to Next Frame" onclick="PlayStepNext();" />
</div>
<div style="float:left;width:24px;">
<img alt="" style="width:24px;width:24px; cursor:pointer;" src="/Content/Images/media_end.png" class="imgPlayEnd" title="Go to Last Frame" onclick="PlayEnd();" />
</div>
<div style="float:left;width:24px;">
<img alt="" style="width:24px;width:24px; cursor:pointer;" src="/Content/Images/LiveFeed.png" class="imgLiveFeed" title="Back to Live Feed" onclick="LiveFeed();" />
</div>
</div>
</div>

So the canvas creates weird behaviour when double clicked. I found and answer that supposed that in order for it to work properly you can cancel out the events that are triggered by:
document.getElementById('canvas').onmousedown = function(){ return false; };
I grabbed this answer from: HTML Canvas Double Click Highlight Issue which lead to... Clicking inside canvas element selects text
hope this helps people so they don't have to jump around a few questions.

Related

How do i arrange images inside a div?

I am making a project for Uni where I need to upload images to with specified width and height for everyone to see. Its basically equivalent of this: http://www.milliondollarhomepage.com/ . The problems is i have this for the HTML side:
<div id="canvas">
</div>
This is where the pictures are supposed to be uploaded, lets say its size is 1000 x 1000. I am supposed to fit every image there without change its dimensions.
const canvas=document.getElementById('canvas')
const btn = document.getElementById('submit-button');
const image_width=document.getElementById('image_width');
const image_height=document.getElementById('image_height');
btn.addEventListener('click', (event) => {
var x=document.createElement('img');
var color=document.getElementById('color');
if(color.value==='red')
{
x.src='red.png';
}
else if(color.value==='blue')
{
x.src='blue.png';
}
x.width=image_width.value;
x.height=image_height.value
event.preventDefault();
canvas.appendChild(x);
});
This is the Javascript I used, just to see how it works. However when we used different sized images for example we put 3 20x20 and add an 20x40 and finish the rest of the line with 20x20 once i add one more 20x20 it wont start filling the free space to the left of the 20x40, it will start filling to the right of the 20x40.
This is the result.
I wanted the red to fill in the black space left of the blue. Red=50x10 Blue=50x20
What you are trying to do is called a "masonry layout" and they are not very straightforward to implement. It usually requires you to change the flow of your content to run in columns instead of rows.
I'm not even sure that your exact scenario can be accomplished without manual placement, but here is an example of a vertical masonry layout (source: https://codepen.io/iamsaief/pen/jObaoKo):
/* Reset CSS */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body {
background: linear-gradient(45deg, #190f2c, #200b30);
padding: 15px;
}
img {
max-width: 100%;
height: auto;
vertical-align: middle;
display: inline-block;
}
/* Main CSS */
.grid-wrapper > div {
display: flex;
justify-content: center;
align-items: center;
}
.grid-wrapper > div > img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 5px;
}
.grid-wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fit, minmax(75px, 1fr));
grid-auto-rows: 100px;
grid-auto-flow: dense;
}
.grid-wrapper .wide {
grid-column: span 2;
}
.grid-wrapper .tall {
grid-row: span 2;
}
.grid-wrapper .big {
grid-column: span 2;
grid-row: span 2;
}
<div class="grid-wrapper">
<div>
<img src="https://images.unsplash.com/photo-1541845157-a6d2d100c931?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80" alt="" />
</div>
<div>
<img src="https://images.unsplash.com/photo-1588282322673-c31965a75c3e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1351&q=80" alt="" />
</div>
<div class="tall">
<img src="https://images.unsplash.com/photo-1588117472013-59bb13edafec?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60" alt="">
</div>
<div class="wide">
<img src="https://images.unsplash.com/photo-1587588354456-ae376af71a25?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80" alt="" />
</div>
<div>
<img src=" https://images.unsplash.com/photo-1558980663-3685c1d673c4?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1000&q=60" alt="" />
</div>
<div class="tall">
<img src="https://images.unsplash.com/photo-1588499756884-d72584d84df5?ixlib=rb-1.2.1&auto=format&fit=crop&w=2134&q=80" alt="" />
</div>
<div class="big">
<img src="https://images.unsplash.com/photo-1588492885706-b8917f06df77?ixlib=rb-1.2.1&auto=format&fit=crop&w=1951&q=80" alt="" />
</div>
<div>
<img src="https://images.unsplash.com/photo-1588247866001-68fa8c438dd7?ixlib=rb-1.2.1&auto=format&fit=crop&w=564&q=80" alt="" />
</div>
<div class="wide">
<img src="https://images.unsplash.com/photo-1586521995568-39abaa0c2311?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80" alt="" />
</div>
<div class="big">
<img src="https://images.unsplash.com/photo-1572914857229-37bf6ee8101c?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1951&q=80" alt="" />
</div>
<div class="tall">
<img src="https://images.unsplash.com/photo-1588453862014-cd1a9ad06a12?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=634&q=80" alt="" />
</div>
<div>
<img src="https://images.unsplash.com/photo-1588414734732-660b07304ddb?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=675&q=80" alt="" />
</div>
<div>
<img src="https://images.unsplash.com/photo-1588224575346-501f5880ef29?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=700&q=80" alt="" />
</div>
<div>
<img src="https://images.unsplash.com/photo-1574798834926-b39501d8eda2?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=800&q=80" alt="" />
</div>
<div>
<img src="https://images.unsplash.com/photo-1547234935-80c7145ec969?ixlib=rb-1.2.1&auto=format&fit=crop&w=1353&q=80" alt="" />
</div>
<div class="wide">
<img src="https://images.unsplash.com/photo-1588263823647-ce3546d42bfe?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=675&q=80" alt="" />
</div>
<div>
<img src="https://images.unsplash.com/photo-1587732608058-5ccfedd3ea63?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80" alt="" />
</div>
<div>
<img src="https://images.unsplash.com/photo-1587897773780-fe72528d5081?ixlib=rb-1.2.1&auto=format&fit=crop&w=1489&q=80" alt="" />
</div>
<div class="wide">
<img src="https://images.unsplash.com/photo-1588083949404-c4f1ed1323b3?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1489&q=80" alt="" />
</div>
<div>
<img src="https://images.unsplash.com/photo-1587572236558-a3751c6d42c0?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80" alt="" />
</div>
<div class="wide">
<img src="https://images.unsplash.com/photo-1583542225715-473a32c9b0ef?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80" alt="" />
</div>
<div class="big">
<img src="https://images.unsplash.com/photo-1527928159272-7d012024eb74?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80" alt="" />
</div>
<div>
<img src="https://images.unsplash.com/photo-1553984840-b8cbc34f5215?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80" alt="" />
</div>
<div>
<img src="https://images.unsplash.com/photo-1433446787703-42d5bf446876?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1351&q=80" alt="" />
</div>
<div class="big">
<img src="https://images.unsplash.com/photo-1541187714594-731deadcd16a?ixlib=rb-1.2.1&auto=format&fit=crop&w=700&q=80" alt="" />
</div>
<div class="tall">
<img src="https://images.unsplash.com/photo-1540979388789-6cee28a1cdc9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=634&q=80" alt="" />
</div>
<div>
<img src="https://images.unsplash.com/photo-1421930866250-aa0594cea05c?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1355&q=80" alt="" />
</div>
<div>
<img src="https://images.unsplash.com/photo-1493306454986-c8877a09cbeb?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1381&q=80" alt="" />
</div>
<div class="wide">
<img src="https://images.unsplash.com/photo-1536466528142-f752ae7bdd0c?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80" alt="" />
</div>
</div>

MasonryJS image gallery aligns left on page refresh

So I have this image gallery which I displayed as Pinterest-style Masonry by using MasonryJS. Everything works fine but the problem is when I refresh the page. That is, when I refresh the page, all the images align to the left at first then comes to the actual place. It's like for a couple of milliseconds it goes to that position and comes back to life.
Here's a gif which shows the actual problem:
How can I not have it left-aligned in page refresh? I just wish it to stay in the middle no matter how much I refresh the page.
Here's the code:
jQuery(window).on('load', function(){
$('.modal-grid').masonry({
itemSelector: '.modal-grid-item',
gutter: 10,
isFitWidth: true
});
});
.modal-grid{
margin: 0 auto;
margin-top: 30px;
}
.modal-grid-item {
width: 300px; margin-bottom: 10px;
}
.modal-grid-item img {
width: 100%; height: auto;
}
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://unpkg.com/masonry-layout#4/dist/masonry.pkgd.min.js"></script>
<div class="modal-grid">
<div class="modal-grid-item">
<img src="https://i.imgur.com/m7M9EPX.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/NzD7YF9.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/8zvUjul.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/WNmP9VL.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/0nwzhDV.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/ypdixv8.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/1oHOvK1.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/kpjtht1.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/QAQ0dk6.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/m7M9EPX.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/NzD7YF9.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/8zvUjul.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/WNmP9VL.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/0nwzhDV.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/ypdixv8.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/1oHOvK1.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/kpjtht1.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/QAQ0dk6.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/m7M9EPX.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/NzD7YF9.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/8zvUjul.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/WNmP9VL.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/0nwzhDV.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/ypdixv8.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/1oHOvK1.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/kpjtht1.jpg" />
</div>
<div class="modal-grid-item">
<img src="https://i.imgur.com/QAQ0dk6.jpg" />
</div>
</div>
Masonry has events we can take advantage of, like layoutComplete. I used that to get masonry to load the images while hidden. Once the ready event fires, we trigger Masonry's own layoutComplete event to recalculate the elements. Then we run a callback once to reveal Masonry.
.modal-grid {
opacity: 0; /* jQuery will remove this later */
transition: opacity; /* optional */
}
jQuery(window).on('load', function() {
/* Init your grid like normal but save it to a variable */
const $grid = $('.modal-grid').masonry({
itemSelector: '.modal-grid-item',
gutter: 10,
isFitWidth: true
});
/*
Add a one time eventListener to just run on our hand-made "onLoad" event
*/
$grid.one('layoutComplete', function() {
/* and fade it in */
$grid.css('opacity', '1');
/*
If it is still happening, you can
add a setTimeout to delay the fade effect
*/
/**
let timeoutHandle;
timeoutHandle = setTimeout(function() {
$grid.css('opacity', '1')
// clear the timeout to make explicitly
// sure no extra timers are running
clearTimeout(timeoutHandle);
}, 1000);
*/
});
$(document).ready(function() {
// trigger the event when the document elements
// are ready
$grid.trigger('layoutComplete');
});
});
If you wanna play around with it, you can check out the CodePen here.

How to Change Button Border on Click with Multiple Button Sets so only one set is affected

I have multiple sets of buttons. Each set has 2 buttons - One is active (with border), Other is inactive (without border). My current solution tuns off all active buttons in all sets, while it should only affect the one in its set. Any idea how to solve this?
$(".MobileSwitcherButton").click(function() {
$(".MobileSwitcherButton").removeClass("active");
$(this).addClass("active");
});
.MobileSwitcherButton {border: none;}
.MobileSwitcherButton.active {border: 1px solid black;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="set1">
<img src="https://www.pracovnivozidla.cz/wp-content/uploads/2016/06/Delivery-Icon.png" alt="" class="MobileSwitcherButton active"
id="MobileSwitcherButton1"/>
<img src="https://www.pracovnivozidla.cz/wp-content/uploads/2016/06/Delivery-Icon.png"
alt="" class="MobileSwitcherButton" id="MobileSwitcherButton2"/>
</div>
<div id="set2">
<img src="https://www.pracovnivozidla.cz/wp-content/uploads/2016/06/Delivery-Icon.png" alt="" class="MobileSwitcherButton active"
id="MobileSwitcherButton1"/>
<img src="https://www.pracovnivozidla.cz/wp-content/uploads/2016/06/Delivery-Icon.png"
alt="" class="MobileSwitcherButton" id="MobileSwitcherButton2"/>
</div>
Thank you
You need to navigate to the parent first and remove the class for its children.
$(".MobileSwitcherButton").click(function() {
$(this).parent().find(".MobileSwitcherButton").removeClass("active");
$(this).addClass("active");
});
.MobileSwitcherButton {
border: none;
}
.MobileSwitcherButton.active {
border: 1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="set1">
<img src="https://www.pracovnivozidla.cz/wp-content/uploads/2016/06/Delivery-Icon.png" alt="" class="MobileSwitcherButton active" id="MobileSwitcherButton1" />
<img src="https://www.pracovnivozidla.cz/wp-content/uploads/2016/06/Delivery-Icon.png" alt="" class="MobileSwitcherButton" id="MobileSwitcherButton2" />
</div>
<div id="set2">
<img src="https://www.pracovnivozidla.cz/wp-content/uploads/2016/06/Delivery-Icon.png" alt="" class="MobileSwitcherButton active" id="MobileSwitcherButton1" />
<img src="https://www.pracovnivozidla.cz/wp-content/uploads/2016/06/Delivery-Icon.png" alt="" class="MobileSwitcherButton" id="MobileSwitcherButton2" />
</div>
Instead of setting up the event handler on the images, set it up on the div parent elements. This will allow you to work with individual sets rather than all the sets at once.
Then, in that handler, look for the images (within the div that the event was handled on) and remove all .active classes from those.
Finally, add back the .active class to the element that originated the event.
// Set up the handler on the various image set containers
$("div[id^='set']").click(function(event) {
// Find all the images within the container that handled the click
$(".MobileSwitcherButton", this.closest("div")).removeClass("active");
$(event.target).addClass("active"); // Add the class to the event originator
});
.MobileSwitcherButton {border: none;}
.MobileSwitcherButton.active {border: 1px solid black;}
/* Only added to show more sets on one screen for demo: */
img { width:40px; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="set1">
<img src="https://www.pracovnivozidla.cz/wp-content/uploads/2016/06/Delivery-Icon.png" alt="" class="MobileSwitcherButton active">
<img src="https://www.pracovnivozidla.cz/wp-content/uploads/2016/06/Delivery-Icon.png" alt="" class="MobileSwitcherButton">
</div>
<div id="set2">
<img src="https://www.pracovnivozidla.cz/wp-content/uploads/2016/06/Delivery-Icon.png" alt="" class="MobileSwitcherButton active">
<img src="https://www.pracovnivozidla.cz/wp-content/uploads/2016/06/Delivery-Icon.png" alt="" class="MobileSwitcherButton">
</div>
<div id="set3">
<img src="https://www.pracovnivozidla.cz/wp-content/uploads/2016/06/Delivery-Icon.png" alt="" class="MobileSwitcherButton active">
<img src="https://www.pracovnivozidla.cz/wp-content/uploads/2016/06/Delivery-Icon.png" alt="" class="MobileSwitcherButton">
</div>
<div id="set4">
<img src="https://www.pracovnivozidla.cz/wp-content/uploads/2016/06/Delivery-Icon.png" alt="" class="MobileSwitcherButton active">
<img src="https://www.pracovnivozidla.cz/wp-content/uploads/2016/06/Delivery-Icon.png" alt="" class="MobileSwitcherButton">
</div>

Replace alt text attribute of images getting text in paragraph

I'm trying to get text in paragraph ".name" and put into all alt attribute in an image gallery. How can i get this text and put into attribute changing the current text. For example: in .box-product one the image of product 0001 should get alt text from this paragraph Box 0001 and another blocks the same respectly.
$(document).ready(function() {
for (i = 0; i < document.getElementsByClassName("box-product").length; i++) {
document.getElementsByClassName("name")[i].setAttribute(
"alt", document.getElementsByTagName("img")[i].src);
}
});
.box-product {
display: inline-block;
border: 1px gray solid;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Product Gallery -->
<div class="gallery-products">
<!-- Product 0001 -->
<div class="box-product">
<a id="product" href="#" class="details">
<p class="image">
<img src="https://upload.wikimedia.org/wikipedia/commons/4/4f/3_D-Box.jpg" height="100" alt="Replace this alt" id="" />
</p>
</a>
<p class="name">Box 0002</p>
</div>
<!-- Product 0002 -->
<div class="box-product">
<a id="product" href="#" class="details">
<p class="image">
<img src="https://upload.wikimedia.org/wikipedia/commons/4/4f/3_D-Box.jpg" height="100" alt="Replace this alt" id="" />
</p>
</a>
<p class="name">Box 0002</p>
</div>
<!-- Product 0003 -->
<div class="box-product">
<a id="product" href="#" class="details">
<p class="image">
<img src="https://upload.wikimedia.org/wikipedia/commons/4/4f/3_D-Box.jpg" height="100" alt="Replace this alt" id="" />
</p>
</a>
<p class="name">Box 0003</p>
</div>
</div>
Perhaps you meant this?
I use jQuery for all the access - you had typos in your DOM access
$(function() {
$(".box-product").each(function() {
$(this).find("img").attr("alt",$(this).find("p.name").text());
});
});
.box-product {
display: inline-block;
border: 1px gray solid;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Product Gallery -->
<div class="gallery-products">
<!-- Product 0001 -->
<div class="box-product">
<a id="product" href="#" class="details">
<p class="image">
<img src="https://upload.wikimedia.org/wikipedia/commons/4/4f/3_D-Box.jpg" height="100" alt="Replace this alt" id="" />
</p>
</a>
<p class="name">Box 0002</p>
</div>
<!-- Product 0002 -->
<div class="box-product">
<a id="product" href="#" class="details">
<p class="image">
<img src="https://upload.wikimedia.org/wikipedia/commons/4/4f/3_D-Box.jpg" height="100" alt="Replace this alt" id="" />
</p>
</a>
<p class="name">Box 0002</p>
</div>
<!-- Product 0003 -->
<div class="box-product">
<a id="product" href="#" class="details">
<p class="image">
<img src="https://upload.wikimedia.org/wikipedia/commons/4/4f/3_D-Box.jpg" height="100" alt="Replace this alt" id="" />
</p>
</a>
<p class="name">Box 0003</p>
</div>
</div>
With jQuery,
$('.box-product').each(function() {
$(this).children('img').attr('alt', $(this).children('.name').text());
});
Basically, $('.box-product') gets all of the boxes. Then you need to loop through each, getting the text from it's child .name and assigning it to the alt attribute of it's child img.
Without jQuery, you can use the querySelectorAll and querySelector functions to easily the same.
document.querySelectorAll('.box-product').forEach(function() {
this.querySelector('img').alt = this.querySelector('.name').innerText;
});
And without those functions (for older browsers):
var products = document.getElementsByClassName('box-product');
for(i in products) {
var product = products[i];
product.getElementsByTagName('img')[0].setAttribute('alt', product.getElementsByClassName('name')[0].innerText);
}

Lazy loading images that are appended by appendChild() in javascript/leaflet

I'm working on a website, http://atlantaartmap.com, which uses leaflet/mapbox to plot street art around Atlanta. The image details are read from a geojson file. While leaflet is reading the geojson, I append thumbnails to a nav bar at the bottom that also link to the corresponding map marker. Appending the images instead of hard coding them allows me to update a single file to change all aspects of the page.
I am attempting to use lazy load on these images, but it doesn't seem to work with items that are appended using java script. Any tips?
Here is the lazy version of the page I am testing: http://atlantaartmap.com/lazy.html
Here is the normal version of the site: http://atlantaartmap.com
Thanks in advance.
edit: For clarification, I would like the lazy loading script to avoid loading images until they are within the window.
I would just throw out the plugin and do that yourself, it's actually very simple to do. You create one image element with your loading image as source, append that as a child to your a (link) element:
var image = new Image();
image.src = 'images/loading.gif';
link.appendChild(image);
Next up you create another image element with your actual image as a source, but you don't need to append it to anything. Just listen for the onload event to fire, then swap the sources:
var original = new Image();
original.src = feature.properties.image;
original.onload = function () {
image.src = original.src;
}
That should work like a charm. Now you can leave out jQuery and the plugin so that's two dependency assets less to load, so your page is loading faster also. Win/win situation if you ask me ;)
Here's a example of the concept on JSFiddle: http://jsfiddle.net/waud32ta/
I really would suggest that you try lazySizes. Different to other lazyloaders it is a self-initializing script, which automatically detects new elements and their visibility. So you don't need to call or configure anything here. Simply append an image with the class lazyload and add your source to the data-src attribute. That's it:
<img src="spinner.gif" data-src="image.jpg" class="lazyload" />
Here is a simple demo.
window.lazySizesConfig = window.lazySizesConfig || {};
window.lazySizesConfig.expand = 40;
window.lazySizesConfig.addClasses = true;
document.querySelector('.add').onclick = function(){
document.querySelector('.scroll-doc').innerHTML = document.querySelector('.template').innerHTML;
};
.scroll-area {
overflow-x: auto;
overflow-y: hidden;
position: relative;
width: 80%;
margin: auto;
padding: 2px 2px 10px;
}
.scroll-doc {
display: table;
position: relative;
text-align: left;
}
.scroll-item {
display: table-cell;
vertical-align: middle;
padding: 10px;
}
.intrinsic {
position: relative;
padding-bottom: 75%;
height: 0px;
}
.lazyload,
.lazyloading {
opacity: 0;
}
.lazyloaded {
opacity: 1;
transition: opacity 300ms;
}
.add {
font-size: large;
font-weight: bold;
}
<script src="http://afarkas.github.io/lazysizes/lazysizes.min.js"></script>
<button type="button" class="add">add to scroll area</button>
<div class="scroll-area">
<div class="scroll-doc"></div>
</div>
<script type="text/html" class="template">
<div class="scroll-item">
<div class="intrinsic">
<img
class="lazyload"
data-src="http://lorempixel.com/400/300/animals/1"
alt="" />
</div>
</div>
<div class="scroll-item">
<div class="intrinsic">
<img
class="lazyload"
data-src="http://lorempixel.com/400/300/animals/2"
alt="" />
</div>
</div>
<div class="scroll-item">
<div class="intrinsic">
<img
class="lazyload"
data-src="http://lorempixel.com/400/300/animals/3"
alt="" />
</div>
</div>
<div class="scroll-item">
<div class="intrinsic">
<img
class="lazyload"
data-src="http://lorempixel.com/400/300/animals/4"
alt="" />
</div>
</div>
<div class="scroll-item">
<div class="intrinsic">
<img
class="lazyload"
data-src="http://lorempixel.com/400/300/animals/5"
alt="" />
</div>
</div>
<div class="scroll-item">
<div class="intrinsic">
<img
class="lazyload"
data-src="http://lorempixel.com/400/300/animals/6"
alt="" />
</div>
</div>
<div class="scroll-item">
<div class="intrinsic">
<img
class="lazyload"
data-src="http://lorempixel.com/400/300/animals/7"
alt="" />
</div>
</div>
<div class="scroll-item">
<div class="intrinsic">
<img
class="lazyload"
data-src="http://lorempixel.com/400/300/animals/8"
alt="" />
</div>
</div>
<div class="scroll-item">
<div class="intrinsic">
<img
class="lazyload"
data-src="http://lorempixel.com/400/300/animals/9"
alt="" />
</div>
</div>
<div class="scroll-item">
<div class="intrinsic">
<img
class="lazyload"
data-src="http://lorempixel.com/400/300/food/1"
alt="" />
</div>
</div>
<div class="scroll-item">
<div class="intrinsic">
<img
class="lazyload"
data-src="http://lorempixel.com/400/300/food/2"
alt="" />
</div>
</div>
<div class="scroll-item">
<div class="intrinsic">
<img
class="lazyload"
data-src="http://lorempixel.com/400/300/food/3"
alt="" />
</div>
</div>
<div class="scroll-item">
<div class="intrinsic">
<img
class="lazyload"
data-src="http://lorempixel.com/400/300/food/4"
alt="" />
</div>
</div>
<div class="scroll-item">
<div class="intrinsic">
<img
class="lazyload"
data-src="http://lorempixel.com/400/300/food/5"
alt="" />
</div>
</div>
<div class="scroll-item">
<div class="intrinsic">
<img
class="lazyload"
data-src="http://lorempixel.com/400/300/food/6"
alt="" />
</div>
</div>
<div class="scroll-item">
<div class="intrinsic">
<img
class="lazyload"
data-src="http://lorempixel.com/400/300/food/7"
alt="" />
</div>
</div>
<div class="scroll-item">
<div class="intrinsic">
<img
class="lazyload"
data-src="http://lorempixel.com/400/300/food/8"
alt="" />
</div>
</div>
<div class="scroll-item">
<div class="intrinsic">
<img
class="lazyload"
data-src="http://lorempixel.com/400/300/food/9"
alt="" />
</div>
</div>
</script>
Try calling
$("img.navthumb").lazyload();
after the thumbnail code has been dynamically injected using JavaScript method appendChild().
Also, i would be able to help you better if you post a JSFiddle.
Hope it helps!!!
Okay, so far you have highlighted that jQuery should be avoided. But I think it's possible to use micro-plugins which contains only the logic you really need. One of them is justlazy. It's a lazy loading library which has no external dependencies and provides compact image loading code.
First, you have to define your placeholders:
<span data-src="path/to/image" data-alt="some alt text"
data-title="some title"
class="justlazy-placeholder">
</span>
It's also possible to define the placeholder as img-tag to be more SEO friendly. One other feature is the loading of responsive images with srcset attribute.
The second step is to initialize the lazy loading via javascript:
Justlazy.registerLazyLoadByClass("justlazy-placeholder"{
// defines that the image will be loaded
// 200 pixels before it gets visible
threshold: 200
});

Categories