I am trying to build a pop-up function written in JavaScript but I feel the code could be better.
So I have two thumbnails and when click it shows the corresponding image but bigger.
I want to build a page with about 20 of these but I feel there will be a lot of code repetition and I am stuck.
My code is here:
https://codesandbox.io/s/i8b1s
Here is my JS:
/*
The goal of this is to simplify the JS code as when I add more images
I do want to keep duplicating code.
*/
// Tesing
const targetNum = document.querySelectorAll("target");
console.log(targetNum);
// Original code below
// Target 1
const target1 = document.querySelector(".counterNo1");
const target2 = document.querySelector(".counterNo2");
// Target 1 Pop Up
const target1MainImage = document.querySelector(".mainImage1");
const target2MainImage = document.querySelector(".mainImage2");
// Close buttons
const close1 = document.querySelector(".closeBTN1");
const close2 = document.querySelector(".closeBTN2");
//Target 1 Clicked Event
target1.addEventListener("click", function () {
console.log("Target 1");
target1MainImage.classList.remove("hide");
target1MainImage.classList.add("show");
});
//Target 2 Clicked Event
target2.addEventListener("click", function () {
console.log("Target 2");
target2MainImage.classList.remove("hide");
target2MainImage.classList.add("show");
});
// Close
//Close Event 1
close1.addEventListener("click", function () {
console.log("Close Target 1");
target1MainImage.classList.add("hide");
target1MainImage.classList.remove("show");
});
//Close Event 2
close2.addEventListener("click", function () {
console.log("Close Target 2");
target2MainImage.classList.add("hide");
target2MainImage.classList.remove("show");
});
As you can see if I have more that one pop up, I am duplicating event listeners etc and I do not want a lot of dup code for elements. This is where I am stuck.
Can anyone point me in the right direction on what to do please?
Thanks,
Ben.
so what you can do is create a common popup and let there be 20 targets on the page. so all you have to do then is
// here create a variable to map the location or src value of bigger image
const ImageMapper = {
one: '/images/one.jpg'
.....
}
// then create the function which calls the popup and set the src of the image element in it
const openPopup = (opener) => {
popupImage.src = ImageMapper[opener]
popup.classList.add('show')
}
// and in the poup add a button which closes the popup so that you dont have to write multiple functions just to close a single popup
const closePopup = () => {
popup.classList.add('hide')
}
// and last in each of the possible element that will open the popup just add the onclick handler like
target1.onclick = () => {
openPopup('one')
}
// this will require a lot less code then what you will have to write
Related
I'm new to JavaScript and I need an image to "disappear" after clicking on it 10 times. What code do I use to make that happen?
You can use a counter variable to keep track of the number of clicks.
Your HTML:
<img src='your-img.jpg'/>
Your JavaScript:
const img = document.querySelector('img'); // Selects the image in your HTML.
let numberOfClicks = 0; // Initialize the counter
const advanceCounter = () => numberOfClicks++; // This is a function that if called, advances the counter by 1.
// Apply a 'click' event listener
img.onclick = function(ev) {
if (numberOfClicks >= 10)
this.style.display = 'none'
else advanceCounter()
}
You can done this with single line of code
<img src="/test.png" onclick="window.counter=(window.counter??0)+1;window.counter>=10?this.remove():null">
window.counter is global variable which increment and if its reach 10 click its will remove its own element
I am tweaking the code of a chrome extension to display the content of a page element in the tab title and scroll it fir navigating open ticket tabs easer. As below
// Need to change this, mousemove listener is super harsh on resource
document.addEventListener("mousemove", function() {
// call the banner element
let bannerTextElements = document.getElementsByClassName("cw_BannerView");
// console.log(bannerTextElements);
// console.log(bannerTextElements[0]);
if (bannerTextElements[0]) {
// console.log("ok");
// console.log(bannerTextElements[0].innerHTML);
// Find and get ticket detail
let bannerTextLine = bannerTextElements[0].getElementsByClassName("detailLabel");
// console.log(bannerTextLine);
if (bannerTextLine[0]) {
// console.log(bannerTextLine[0].innerHTML);
// Trim "Service Ticket for cleanness Need to do this for 'Manage' too"
let tickettext = bannerTextLine[0].innerHTML.split("Manage ");
let tickettext1 = bannerTextLine[0].innerHTML.split("Service Ticket ");
// console.log(tickettext[0]);
// console.log(tickettext[1]);
// Set the title equal to everything after "Service Ticket"
if (tickettext1[1]) {
document.title = tickettext1[1];
// now works!! bit clunky though
var documentTitle = tickettext1 + " - ";
(function titleMarquee() {
document.title = documentTitle = documentTitle.substring(1) +
documentTitle.substring(0,1);
setTimeout(titleMarquee, 160);
})();
} else {
// For everything else, just display what's already there
document.title = tickettext1[0];
}
}
}
}, false);
(ignore the appalling indents i promise thats just on this post! )
However, due to the slow page load the only eventlistener i can get to pick the content of the banner text is 'mousemove' which naturally has the negative side effects of A. Firing infinite times as you view the page and also resetting the scroll to the start as you mouse over.
document.OnLoad and window.onload just stops this working and it loads the default tab title
Is there a way to get onLoad to run after an arbitrary delay, say 10s or to check to make sure that the classname cw_bannerview is loaded up and populate with the ticket title?
I know that there are many questions and answers pertaining this, but i have tried but am still unable to do so. Please help.
Here is my js code:
$(document).ready(clicklistener); // once ready, run clicklistener function
function clicklistener() {
$(".image-thumbnail").click(popup); // run popup function when ".image-thumbnail" is clicked}
function popup() {
var srcname = $(this).attr("src"); // get source image filename
var newfile = srcname.replace("small", "large"); // replace with large img
if ($(this).parent().children("span").children("img").hasClass("image-popup")) { // traverse the elements to check if the image popup already exists
$(this).parent().children("span").remove(); // remove if it already exists
} else {
var printimg = "<span><img class=\"image-popup\"src=\"" + newfile + "\"></img></span>";
$(this).after(printimg); // create img if it doesn't exist
}}
Doesn't look like you have an event defined for closing it (unless you click on the popup). SO you need to write one:
$(document).ready(function(){
$(".image-thumbnail").click(function(){
// allow for body.click to first hide any current images
setTimeout(function(){popup($(this))}, 600)); // run popup function when ".image-thumbnail" is clicked
});
function popup($ele) {
var srcname = $ele.attr("src"); // get source image filename
var newfile = srcname.replace("small", "large"); // replace with large img
if ($ele.parent().children("span").children("img").hasClass("image-popup")) { // traverse the elements to check if the image popup already exists
$ele.parent().children("span").remove(); // remove if it already exists
} else {
var printimg = "<span><img class=\"image-popup\"src=\"" + newfile + "\"></img></span>";
$ele.after(printimg); // create img if it doesn't exist
}
}
$(window).click(function(){
$('.image-popup').remove()
});
})
I hope you have a good day :)
I am working on a plugin currently. I would like to loop through all the articles: on click => open a popp-up, when the pop-up closes => show this content ... My code only works for the first article. Sorry if that seems trivial to you, if you have links or tutorials to advise me, I am interested :)
Thank you !
function socialLocker() {
let sl = document.querySelector(".ws-sl-container");
let slc = document.querySelector(".ws-sl-content");
document.querySelectorAll(".ws-sl-box-for-social-medias a").forEach(function(ele) {
ele.onclick = function(e) {
var web_window = window.open(this.href, 'Share Link', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600,top=' + (screen.height/2 - 300) + ',left=' + (screen.width/2 - 300));
var check_window_close = setInterval(function() {
if (web_window.closed) {
clearInterval(check_window_close);
sl.style.display = "none";
slc.style.display = "block";
}
}, 1000);
e.preventDefault();
};
});
};
It seems to be a problem with selecting the elements in the document.
You can use next selector: https://api.jquery.com/next/ instead of selecting all and looping with foreach. With next, you will get the closest element.
Suppose all the posts in your list have a button with the class trigger and when clicked it shows a popup with the class of popup.
<script>
jQuery(document).ready(function(){
jQuery(".popup").hide(); /* hide all popups */
jQuery(".trigger").click(function(){ /* when button is clicked */
jQuery(this).next(".popup").slideToggle(); /* toggle the closest popup */
});
});
</script>
This way the click / action (you want to have it when closed) on (this) element will affect nearest element.
I have the following code which is not working
jQuery
jQuery(window).bind("load", function() {
function effects(content_name,active_name)
{
// switch all tabs off
$(active_name).removeClass("active");
// switch this tab on
$(this).addClass("active");
// slide all content up
$(content_name).slideUp();
// slide this content up
var content_show = $(this).attr("title");
$("#"+content_show).slideDown();
}
$("a.tab_1").click(function () {
var content_name = '.content_a';
var active_name = 'a.tab_1.active';
effects(content_name,active_name);
});
$("a.tab_2").click(function () {
var content_name = '.content_b';
var active_name = 'a.tab_2.active';
effects(content_name,active_name);
});
$("a.tab_3").click(function () {
var content_name = '.content_c';
var active_name = 'a.tab_3.active';
effects(content_name,active_name);//create effects with the content
});
});
Its a set of tab groups upto 8 in number. Writing individual functions will have an adverse effect on loading time.
Answer 2 hours later:
Thank you all for pointing out the "effetcs" mistake in the code.
The other mistake was I was doing was not passing "$(this)" as a parameter into the called function "effects".
I Have adjoined the link where the necessary changes are done and the code works.
[jsfiddle] http://jsfiddle.net/phyGS/2/
Replace effetcs with effects at the first block, and replace every occurrence of
effects(content_name,active_name);
with
effects.call(this, content_name, active_name);
This call method assigns a new value to the this property of function effects.