Heres the Javascript code:
function showCard(linkTarget) {
var propertyWidth = 400;
var propertyHeight = 350;
var winLeft = (screen.width-propertyWidth)/2;
var winTop = (screen.height-propetyHeight)/2;
var winOptions = "toolbar=no,menubar=no,location=no,scrollbars=yes,resizable=no";
winOptions += ",width=" + propertyWidth;
winOptions += ",height=" + propertyHeight;
winOptions += ",left=" + winLeft;
winOptions += ",winTop=" + winTop;
cardWindow = window.open(link.target,"cardInfo", winOptions);
cardWindow.focus();
}
var cardWindow;
href="valentine.jpg" onclick="showCard('valentine.jpg');return false">Valentine's Day
(I removed the tags because the code is not showing up with them)
window.open(link.target...) should be window.open(linkTarget...)
This is causing an error, so the return false; is never reached and the link navigates as normal.
Looks to me like your problem is here:
Your function is declared as:
function showCard(linkTarget)
but you refer to the parameter passed in later in the code with a dot as
cardWindow = window.open(link.target,"cardInfo",winOptions);
Related
Context
I've used the "Intersection Observer API" to build an infinite scroll image gallery. Basically this API allows me to load more items when a certain dummy DOM element enters the viewport.
Prototype
Currently the prototype is implemented for an “iPhone X” (375x812) mobile device only. See: http://urbexco-acceptance.droppages.com/min_rep_ex_working (use Chrome DevTools 'inspect' device toolbar to select the right resolution). The image gallery is generated based on 57 items in the "database". When scrolling down, first 15 elements are loaded, then 15 more elements are loaded, then another 15 elements are loaded into the DOM, then another 10 elements are loaded, and finally 2 elements are loaded. When there are still more than 15 items left to be loaded, they are added using the following logic:
function addItems(n){
// Append new items to .items-wrapper
var items = document.querySelector('.items-wrapper');
for (var i = 0; i < n; i++) {
var url = 'https://img01.ztat.net/article/spp-media-p1/09742e38c25b3e1d9716e02f8e76e87d/89fc0bda6a2c446a8e9e0d8adbc9a4fe.jpg';
width = 170.5;
height = 246;
var newDiv = document.createElement('div');
newDiv.classList.add('item');
items.appendChild(newDiv);
newDiv.innerHTML = "<img src=" + '"' + url + '"' + "width=" + '"' + width + '"' + "height=" + height + "/>";
}
}
Minimal Working Example (no mobile view possible)
https://jsfiddle.net/9jqgzymo/
Objective
Since image width and height are currently hardcoded, I am now trying to assign width and height dynamically based on the image url. I try to achieve this using the getMeta() function:
function addItems(n){
// Append new items to .items-wrapper
var items = document.querySelector('.items-wrapper');
for (var i = 0; i < n; i++) {
var url = 'https://img01.ztat.net/article/spp-media-p1/09742e38c25b3e1d9716e02f8e76e87d/89fc0bda6a2c446a8e9e0d8adbc9a4fe.jpg';
getMeta(url);
}
}
function getMeta(url){
var img = new Image();
img.onload = function(){
res = calculateAspectRatioFit(this.width, this.height, 170.5, 246)
var newDiv = document.createElement('div');
newDiv.classList.add('item');
var items = document.querySelector('.items-wrapper');
items.appendChild(newDiv);
newDiv.innerHTML = "<img src=" + '"' + url + '"' + "width=" + '"' + res.width + '"' + "height=" + res.height + "/>";
};
img.src = url;
}
function calculateAspectRatioFit(srcWidth, srcHeight, maxWidth, maxHeight) {
var ratio = Math.min(maxWidth / srcWidth, maxHeight / srcHeight);
return { width: srcWidth*ratio, height: srcHeight*ratio };
}
Challenge
When implementing it this way, I see that - on initiation - already 30 items from the "database" where added to the DOM. Sometimes even all of them? Currently the non-working prototype is implemented for an “iPhone X” (375x812) mobile device only. See: http://urbexco-acceptance.droppages.com/min_rep_ex_not_working (use Chrome DevTools 'inspect' device toolbar to select the right resolution). For a minimal working example, see: https://jsfiddle.net/k3p20qno/
Key question
What is the reason that with my new implementation, on initiation, already 30 or more items are added to the DOM? How can I fix it?
Well the problem lies in here :
function getMeta(url){
var img = new Image();
img.onload = function(){
res = calculateAspectRatioFit(this.width, this.height, 170.5, 246)
var newDiv = document.createElement('div');
newDiv.classList.add('item');
var items = document.querySelector('.items-wrapper');
items.appendChild(newDiv);
newDiv.innerHTML = "<img src=" + '"' + url + '"' + "width=" + '"' + res.width + '"' + "height=" + res.height + "/>";
};
img.src = url;
}
Above code does an async operation with onload event. So it doesn't wait to image to be loaded.
If you turn this into a function that returns a promise you will get the result that you expect. And you should await where you call the function. That way when you add the intersection element it will add it as the last element of the items wrapper. If you don't await it will be added as the first element because the loading of the images will be async and will happen later.
function getMeta(url){
var img = new Image();
const p = new Promise(resolve =>{
img.onload = function(){
console.log( this.width+' '+ this.height );
res = calculateAspectRatioFit(this.width, this.height, 170.5, 246)
var newDiv = document.createElement('div');
newDiv.classList.add('item');
var items = document.querySelector('.items-wrapper');
items.appendChild(newDiv);
newDiv.innerHTML = "<img src=" + '"' + url + '"' + "width=" + '"' + res.width + '"' + "height=" + res.height + "/>";
resolve()
};
})
img.src = url;
return p;
}
Fiddle
Edit: Put the resolve() in the right position which is inside the load function
I have a code that puts images on a table(html), and I want to focus on the image that has just appeared.
I know that i have to use $(this) but i don't know how, here is my code
function positioning(year, mon) {
$('#' + year + ' .' + mon).prepend('<img class="black_point" src="./images/circle.png"/>');//that adds the image
var table = document.getElementById("table");
var images = table.getElementsByTagName("img");
//here I need the current image I had just add to send to that function
function connect(images) {
var tabBcr = table.getBoundingClientRect();
var imgBcr = image.getBoundingClientRect();
x = imgBcr.left + (imgBcr.width / 2) - tabBcr.left;
y = imgBcr.top + (imgBcr.height / 2) - tabBcr.top;
}
}
I hope I have explained well .
I think it will work, add this where you want to get that img element:
var imgelem=$('#' + year + ' .' + mon).find("img:first");
Please go to: www.designedbychristian.com/template_2
(so far being tested in chrome)
When you click design a bunch of thumbnails appear.
I am trying to use the .each selector to get the src of the image. I want to take that value and apply it to a div that will appear when clicked. (I know how to program that part)
My problem is when I click the thumb nail my alert is giving me the value of all of the thumbnails.
my code is this:
function spawnImages() {
N = 1
for (i = 1; i <= 9; i++) {
var gal = document.getElementById('gallary')
var newDIV = '<img onclick="imageView()" src="images2/image' + N + '.jpg" class="thumb-nail imageNumber' + N + '"/>'
$('.gallary').prepend(newDIV)
var min = 3;
var max = 70;
var s = Math.floor(Math.random() * (max - min + 1)) + min;
var test = $(('.imageNumber' +N)).css("left", s + "%")
var min = 3;
var max = $(this).height();
var max = 70;
var s = Math.floor(Math.random() * (max - min + 1)) + min;
var test = $(('.imageNumber' + N)).css("top", s + "%")
var min = -45;
var max = 45;
var s = Math.floor(Math.random() * (max - min + 1)) + min;
var test = $(('.imageNumber' + N)).css("-webkit-transform", "rotate(" + s + "deg)")
var test = $(('.imageNumber' + N)).css("transform", "rotate(" + s + "deg)")
var test = $(('.imageNumber' + N)).css("-ms-transform", "rotate(" + s + "deg)")
N++
}
}
function imageView() {
$(".thumb-nail").each(function () {
var imageSrc = $(this).attr('src');
alert($(this).attr('src'));
//$('.images').css("background-image", "url("+imageSrc+")");
//$('.images').css("background-size", "cover");
//$('.blackForeground').css("visibility", "visible");
//$('.images').css("visibility", "visible");
})
};
Just use jquery event handlers, get rid of the onclick call in your html and just add this in your javascript.
$(".thumb-nail").on('click', function(){
var imageSrc = $(this).attr('src');
alert($(this).attr('src'));
//$('.images').css("background-image", "url("+imageSrc+")");
//$('.images').css("background-size", "cover");
//$('.blackForeground').css("visibility", "visible");
//$('.images').css("visibility", "visible");
});
EDIT: didn't think about the images being created dynamically, Popnoodles answer is the right one
pass clicked element reference like this:
var newDIV = '<img onclick="imageView(this)" src="images2/image' + N + '.jpg" class="thumb-nail imageNumber' + N + '"/>'
Function:
function imageView(element) {
var imageSrc = $(element).attr('src');
alert($(element).attr('src'));
}
This is exactly how the jQuery API describes the .each() method:
Iterate over a jQuery object, executing a function for each matched element.
When you called $('.thumb-nail') it returned ALL of the elements with the class thumb-nail in a jQuery object. Then when you called .each( function() {} ) on that object, the loop iterated over all of the returned elements.
The easiest way to handle click events in jQuery, is to use the .on() method, as others have pointed out in their answers.
Also, as #Popnoodles mentioned, since these elements are created dynamically, you may need to run your $().on() call explicitly after these elements are created. For that reason, you might wrap it into your spawnImages() function, rather than putting it inside $() as #Popnoodles indicates (i.e. not $( $(element).on('click',function(){}), as $( ) is equivalent to $(document).ready.
The simplest change is this
// send this element to the function
var newDIV = '<img onclick="imageView(this)" src="images2/image' + N + '.jpg" class="thumb-nail imageNumber' + N + '"/>'
function imageView(el) {
var imageSrc = $(el).attr('src');
alert($(el).attr('src'));
};
But it's nice to do things in a more standard fashion...
First get rid of this onclick="imageView()"
var newDIV = '<img src="images2/image' + N + '.jpg" class="thumb-nail imageNumber' + N + '"/>'
Since these elements are created dynamically you will need to bind the click event to document or another ancestor that exists, and delegate to each ".thumb-nail".
You also need to run this procedure only when dom is ready ($(function(){...});).
$(function(){
$(document).on('click', ".thumb-nail", function () {
var imageSrc = $(this).attr('src');
alert($(this).attr('src'));
//$('.images').css("background-image", "url("+imageSrc+")");
//$('.images').css("background-size", "cover");
//$('.blackForeground').css("visibility", "visible");
//$('.images').css("visibility", "visible");
});
});
I use this jQuery code to append a div to another:
$('#sklep').on('click', '.kup', function () {
var cena = $('#cena').text();
var tytul = $('#tytul').text();
var iden = $('#id').text();
var suma = $('#koszykdiv .cyfry').text();
var dodawanie = parseInt(cena) + parseInt(suma);
$('.cyfry').text(dodawanie);
var source = $("#miniatura").attr("src");
$('.koszyk_content_items').append($('<div class="item_koszyk"><div class="miniatura_koszyk"><img width="165" height="110" src="' + source + '"/></div><span id="opis">' + tytul + ' - ' + cena + ' zł - </span><span class="identyfikator" style="display:none;">' + iden + '</span>USUŃ</div>'));
var licznik = $('#koszykdiv .licznik').text();
alert(licznik);
$('#identyfikator').text(licznik);
var licznik_dodawanie = parseInt(licznik) + 1;
$('#koszykdiv .licznik').text(licznik_dodawanie);
$.cookie("obraz" + licznik_dodawanie, id);
var cena = '';
var tytul = '';
var iden = '';
var source = '';
});
but it always appends a div with the same variables values, even if parent of '.kup' href has another text values. Can you help me and tell where the problem is?
You say in your question that you get the same variable values "even if parent of '.kup' href has another text values."
This is because nothing in your code is relative to the '.kup'-element. You get the src-attribute of the element with id=miniatura everytime.
I have an aspx page with a button. When the user clicks that button, the following javascript opens a new browser window (in this case, 'Reasons.aspx'). Works great. Here's the function for that part:
function ShowPanel(url)
{
var width = 750;
var height = 600;
var left = (screen.width - width) / 2;
var top = (screen.height - height) / 2;
var params = 'width=' + width + ', height=' + height;
params += ', top=' + top + ', left=' + left;
params += ', toolbar=no';
params += ', menubar=no';
params += ', resizable=yes';
params += ', directories=no';
params += ', scrollbars=no';
params += ', status=no';
params += ', location=no';
newwin = window.open(url + '?LetterNumber=1&ReasonType=3', 'd', params); //<--- Change This (LetterNumber) When Copying!
if (window.focus)
{
newwin.focus()
}
return false;
}
Now here's where it gets funky. When this window pops up, there are some controls. One of which is a button, which triggers almost identical code to popup a third window (in this case, ReasonCodes.aspx). Only it won't work. Here's the code for that:
function fGetReasons(url)
{
var width = 750;
var height = 600;
var left = (screen.width - width) / 2;
var top = (screen.height - height) / 2;
var params = 'width=' + width + ', height=' + height;
params += ', top=' + top + ', left=' + left;
params += ', toolbar=no';
params += ', menubar=no';
params += ', resizable=yes';
params += ', directories=no';
params += ', scrollbars=no';
params += ', status=no';
params += ', location=no';
newwin = window.open(url, 'd', params); //<--- Change This (LetterNumber) When Copying!
if (window.focus)
{
newwin.focus()
}
return false;
}
I've set breakpoints on the javascript. It does execute. Here's what's weird -- The above javascript executes, only I don't get a new window with ReasonCodes.aspx. However, I set a breakpoint in the page_load of ReasonCodes.aspx and all of it executes. So the javascript executes, the code-behind page_load of the third page executes, but I don't get a third page.
Instead, the second window (Reasons.aspx) refreshes. It's like my third window is somehow 'hidden'.
Can anybody tell me what's going on, or what am I missing?
Thanks,
Jason
PS -- I know 3 windows sounds like a lot, and it's not by choice. There's a business need here (this is a local intranet application) and I have to abide by the specs. Thanks.
The 2nd parameter to window.open is the name of the window. You are using the same name in both calls so it is attempting to use the same window. Change the name of the 2nd call and you should be fine.
Or use '_blank' name to open each time in new window!