Arranging buttons within a div container with JavaScript exclusively

I am struggling with arranging this gallery to achieve a specific layout. I attempted various methods involving absolute and relative positioning, margins, and other CSS properties, but have not been successful in organizing it properly.

Specifically, the popup div should cover 80% of the page height and 80% of the page width, while ensuring that images do not exceed the boundaries of the div.

I am restricted from altering the HTML or adding CSS. Therefore, all modifications must be made within the JS file.

The following is my current code:

$(document).ready(function() {
  var images = $('div[title ="London gallery"]').children('img').map(function() {
    return $(this).attr('src')
  }).get();
  var description = $('div[title ="London gallery"]').children('p').map(function() {
    return $(this).text();
  }).get();


  $('div[title ="London gallery"]').hide();
  var gallery_lndn = document.createElement('button');
  
  // Rest of the JavaScript code removed for brevity
  
});
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf8">
  <title>Document</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.js"></script>
  <script src="gallery.js"></script>
</head>

<body>
<h1>London</h1>
  <div class="gallery" title="London gallery">
    <img src="https://cdn.londonandpartners.com/visit/general-london/areas/river/76709-640x360-houses-of-parliament-and-london-eye-on-thames-from-above-640.jpg">
            <p data-target="https://cdn.londonandpartners.com/visit/general-london/areas/river/76709-640x360-houses-of-parliament-and-london-eye-on-thames-from-above-640.jpg">
    Description 1.
    </p>  
    <img src="https://news.itu.int/wp-content/uploads/2018/07/london-min-e1530887248858.jpg">
    <p data-target="https://news.itu.int/wp-content/uploads/2018/07/london-min-e1530887248858.jpg">
    Description 2.
    </p>    
  </div>
</body>

</html>

Answer №1

To adjust the button positions based on the image, incorporate the following method within the updateImage function before closing it.

function repositionButtons(){
// set absolute positioning for all buttons
$('#div_popup > button').css({'position': 'absolute', 'float':'none', 'z-index': 1});

// determine the bottom position of the image
let buttonTopPos = ($('#div_popup > img').offset().top + $('#div_popup > img').height()) - $('#div_popup').offset().top + 20;

// identify the bottom left position of the image
let buttonLeftPos = 0;
if($('#div_popup').width() > $('#div_popup > img').width()){
    buttonLeftPos = ($('#div_popup').width() - $('#div_popup > img').width())/2
}else{
   $('#div_popup > img').css({'min-width':'100%', 'max-width':'100%'});
}

// hide overflow for the image container
$('#div_popup').css('overflow', 'hidden');

// Positioning for the Back button
$('#div_popup > button:nth-child(1)').css({'top': buttonTopPos, 'bottom':'auto', 'left': buttonLeftPos +'px'})

// Location of the Next button
$('#div_popup > button:nth-child(2)').css({'top': buttonTopPos, 'bottom':'auto', 'left': (buttonLeftPos + $('#div_popup > img').width()) - 90})

// Set position for the cancel button
$('#div_popup > button:nth-child(3)').css({'top': 0, 'right': 0, left: 'auto'});

// Specify the position for the description
$('#div_popup > span').css({'position': 'absolute','top': buttonTopPos, 'bottom':'auto', 'left': buttonLeftPos + 90, 'width': $('#div_popup > img').width() - 90 - 90, 'text-align': 'center'})
}

Answer №2

Here is a custom layout similar to the example provided above. To make things easier, JavaScript is used to add a <style> element to the <head>.

window.onload = () => {
  const myCSS =
    '    body {\n' +
    '      width:100vw;\n' +
    '      height:100vh;\n' +
    '      position:relative\n' +
    '    }\n' +
    '    .gallery {\n' +
    '      background-color: darkblue;\n' +
    '      width: 80%;\n' +
    '      height: 80%;\n' +
    '      position: absolute;\n' +
    '      top: 10%;\n' +
    '      left: 10%;\n' +
    '    }\n' +
    '    .img-wrapper {\n' +
    '      background-color: transparent;\n' +
    '      width: calc(100% - 120px);\n' +
    '      height: calc(100% - 160px);\n' +
    '      margin: 60px;\n' +
    '      overflow-y: hidden;\n' +
    '    }\n' +
    '    .img-wrapper img {\n' +
    '      width: 100%;\n' +
    '      height: auto;\n' +
    '    }\n' +
    '    .btn1 {\n' +
    '      width: 120px;\n' +
    '      height: 60px;\n' +
    '      position: absolute;\n' +
    '      left: 60px;\n' +
    '      bottom: 30px;\n' +
    '      background-color: #999;\n' +
    '    }\n' +
    '    .btn2 {\n' +
    '      width: 120px;\n' +
    '      height: 60px;\n' +
    '      position: absolute;\n' +
    '      right: 60px;\n' +
    '      bottom: 30px;\n' +
    '      background-color: #999;\n' +
    '    }\n' +
    '    .btn-close {\n' +
    '      width: 80px;\n' +
    '      height: 40px;\n' +
    '      position: absolute;\n' +
    '      right: 0;\n' +
    '      top: 0;\n' +
    '      background-color: #999;\n' +
    '    }\n' +
    '    .caption {\n' +
    '      width: calc(100% - 409px);\n' +
    '      height: 60px;\n' +
    '      position: absolute;\n' +
    '      left: 192px;\n' +
    '      bottom: 30px;\n' +
    '      color: white;\n' +
    '      border: 1px dashed #aaa;\n' +
    '      text-align: center;\n' +
    '      padding: 0 12px;\n' +
    '      overflow: hidden;\n' +
    '    }\n';
  const myStyle = document.createElement('style');
  myStyle.id = 'myCSS';
  myStyle.innerHTML = myCSS;
  document.head.appendChild(myStyle);
}
<body>

  <div class="gallery">
    <div class="img-wrapper">
      <img src="https://cdn.londonandpartners.com/visit/general-london/areas/river/76709-640x360-houses-of-parliament-and-london-eye-on-thames-from-above-640.jpg">
    </div>
    <div class="btn1">.btn1</div>
    <div class="btn2">.btn2</div>
    <div class="caption">.caption</div>
    <div class="btn-close">.btn-close</div>
  </div>
</body>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Challenge with neglected open connections from a comet

Utilizing various comet techniques like long polling and forever frame, along with iframes for cross subdomain activities, has presented a challenge during implementation. When a user refreshes the page or navigates to another page, a new request is made w ...

Stop the anchor tag from activating Chrome's status bar

I've been working on a web application with an elastic layout where the footer acts as a toolbar and information display. The footer is always visible at the bottom of the page, without any need for scrolling. We specifically chose this location for t ...

What is the best method for looping through all text fields in Selenium?

My challenge involves a group of text fields all sharing the same class names. Here is the HTML code: Each text field has identical class names, and I am attempting to automate inputting values into them by using the sendKeys method in Selenium. For this ...

Unable to find the Popper component in Material UI

Material-UI version "@material-ui/core": "^3.7.0" I have a requirement to display Popper on hover over an element, but unfortunately, the Popper is not visible. This section serves as a container for the Popper component. import PropTypes from &apos ...

Creating a web application that efficiently stores and retrieves user preferences

Currently, I am working on developing a Nodejs/Express web application that is similar to a dashboard or homepage for a web browser. The data displayed on the page is customized based on the user's settings. When a user signs up, I create a json file ...

What is the best way to share models across different node.js projects?

In my setup, I have two node.js projects - project A and project B. Project A serves as the main project, while project B is more of an "ad-hoc" project with a specific purpose. The challenge lies in the fact that project B requires access to project A&apo ...

What is the best way to iterate through an object in Typescript? The element currently holds a type of 'any' due to the index expression not being of type 'number'

Obtaining Element implicitly has an 'any' type because the index expression is not of type 'number'. interface User { name: string; username: string; profileImage: string; } let user:User = { name: 'Alice', ...

Implementing animations in JavaScript to create movement by manipulating CSS styles

I'm currently working on making an element move when arrow keys are pressed by using .css(), but for some reason it's not functioning as expected. Oddly enough, the exact same code works perfectly fine with JQ animate(). I'm puzzled as to wh ...

Using angularjs ng-option alongside ng-change

In my model, I have a structure that resembles the following: { id: 1, country: { code: 'GB', name: '' } } While the country code is stored in the database, the name is missing. Another application requires ...

React app's setTimeout function fails to execute at the designated time specified

I have a function set up in my React app to handle user authentication and signup. The function is supposed to display an alert message saying "Account Created" upon successful signup, and then redirect the user to their profile page after a 1-second delay ...

A guide on showcasing the elements of an array within an object using React MobX

I am currently utilizing react and mobx to develop a straightforward event application. However, I am facing an issue with displaying data from a JSON object in my View. Here is an example of the JSON data I am working with: { "events": { "November ...

Having issues with Tailwind classes not being applied properly on dynamically generated pages in Gatsby-node

Currently, I am working on building dynamic pages using gatsby-node. The templates for these pages are stored in the templates/ directory. However, I have run into an issue where I cannot utilize tailwind classes within these templates unless they are al ...

Deactivate dropdown menu selection depending on choice made in another list

I am currently working with the following code: $('select').on('change', function(){ $('select option').prop("disabled", false); $("select").not(this).find("option[value="+ $(this).val() + "]").prop('disabled ...

Adjust the background image height to match the height of the viewport

In my Nuxt.js project with Vuetify.js, I am trying to apply a background image to the entire content section: <v-content> <v-img src="https://picsum.photos/id/11/500/300" > <v-container justify-center fill-he ...

Tips for identifying visible elements on a webpage with JavaScript

My #diagram div is larger than the visible area in my browser and contains up to 1500 "boxes" as div elements. I am looking for a way to determine which of these 1500 boxes are actually visible to the user so that I can dynamically load them using ajax. Cu ...

Uploading files with Angular and NodeJS

I am attempting to achieve the following: When a client submits a form, they include their CV AngularJS sends all the form data (including CV) to the Node server Node then saves the CV on the server However, I am encountering difficulties with this proc ...

Aligning elements to the left in a variable width grid with centered alignment

Let's think about the structure below <div class="container"> <div class="grid"> <div class="unit"></div> <div class="unit"></div> <div class="unit"></div> ...

Is there a way to showcase a single HTML canvas across multiple div elements?

I'm currently developing a web application that includes a Google Maps feature in two different tabs using Twitter Bootstrap. I am exploring options to have one canvas element that can be displayed in both tabs with varying dimensions. One idea is to ...

What is the process for closing the lightbox?

My code is supposed to display a lightbox as soon as the page loads, similar to a popup window. However, there seems to be an issue with closing the lightbox when clicking on the 'x' button at the corner of the box. Unfortunately, the current cod ...

Is it possible to deactivate an element based on a specific string present in the URL?

<div class="custom-class1"> <div class="custom-class2" id="custom-id1">hello 1</div> <div class="custom-class3" id="custom-id2">hello 2</div> <div class="custom-class4" id="custom-id3">hello 3&l ...