Navigate through photos (jQuery) to adjust size and location dynamically (CSS)

Currently, I am in the process of developing a jQuery script that will automatically adjust the size and position of image elements upon page load or resize. To structure my layout, I am utilizing Bootstrap and have set a fixed height using CSS. It is worth mentioning that once development is complete, I will not have the ability to control the images' sizes or aspect ratios.

After successfully creating a local script that handles the calculations and conditional statements for images of varying dimensions and aspect ratios, I now need to encase it within a jQuery each() loop.

My attempts at implementing a single loop surrounding the main script targeting elements with the .listing-box class were met with mixed results. Adding a nested loop to target the actual image inside led to unintended consequences where initial calculations were applied to all subsequent images. My struggle lies in properly incorporating the each() function.

JSBin (single image)

JSBin (multiple images)

HTML

<div class="row">
    <div class="col-sm-3">
        <a href="#">
            <div class="listing-box">
                <div class="listing">
                    <img src="http://placehold.it/600x400" alt="thumbnail" class="thumb">
                </div>
            </div>
        </a>
    </div>
</div>

CSS

.listing-box {
    width: 100%;
    height: 220px;
    position: relative;
    overflow: hidden;
}
.thumb {
    overflow: hidden;
}

jQuery

$(window).on('resize load', function() {
    // get .listing-box width and height
    var boxWidth = $(".listing-box").width();
    var boxHeight = $(".listing-box").height();
    var boxAspect = (boxWidth / boxHeight);

    // get .thumb width and height
    var imgWidth = $(".thumb").width();
    var imgHeight = $(".thumb").height();
    var imgAspect = (imgWidth / imgHeight);

    // set some empty variables
    var newWidth,
        newHeight,
        mTop,
        mLeft;

    if (imgAspect < 1) {
        // image is VERTICAL
        // assign values
        newWidth = boxWidth;
        newHeight = newWidth * imgHeight / imgWidth;
        mTop = (newHeight - boxHeight) / 2;

        // use new values for inline css
        $(".thumb").css({
            width: newWidth + "px",
            height: newHeight + "px",
            marginTop: "-" + mTop + "px"
        });
    } else {
        // image is HORIZONTAL
        if (imgAspect > boxAspect) {
            // image is wider than taller
            // assign values
            newHeight = boxHeight;
            newWidth = newHeight * imgWidth / imgHeight;
            mLeft = (newWidth - boxWidth) / 2;

            // use new values for inline css
            $(".thumb").css({
                width: newWidth + "px",
                height: newHeight + "px",
                marginLeft: "-" + mLeft + "px"
            });
        } else {
            // image is taller than wider
            // assign values
            newWidth = boxWidth;
            newHeight = newWidth * imgHeight / imgWidth;
            mTop = (newHeight - boxHeight) / 2;

            // use new values for inline css
            $(".thumb").css({
                width: newWidth + "px",
                height: newHeight + "px",
                marginTop: "-" + mTop + "px"
            });
        }
    }

});

Although there are various plugins available for this purpose, I am determined to achieve this without relying on any external resources. My primary obstacle lies in effectively implementing looping functionalities.

Answer №1

Great progress! Ensuring that the entire function is enclosed within a .each() loop is key:

$(window).on('resize load', function() {
 $('.listing-box').each(function() {

    var boxWidth = $(".listing-box").width();
    var boxHeight = $(".listing-box").height();
    var boxAspect = (boxWidth / boxHeight);

    // get .thumb width and height
    var imgWidth = $(".thumb").width();
    var imgHeight = $(".thumb").height();
    var imgAspect = (imgWidth / imgHeight);

   // etc...
 });
});

When utilizing this method, jQuery will iterate over each instance of the .listing-box element found, including all associated .listing-box and .thumb elements to apply your sizing logic. To target specific .listing-box elements within the loop along with their respective .thumb children, utilize the this selector:

$(window).on('resize load', function() {
 $('.listing-box').each(function() {

    var boxWidth = $(this).width();
    var boxHeight = $(this).height();
    var boxAspect = (boxWidth / boxHeight);

    var imgWidth = $(this).find('.thumb').width();
    var imgHeight = $(this).find('.thumb').height();
    var imgAspect = (imgWidth / imgHeight);

   // etc...
 });
});

Note: Keep in mind that jQuery passes standard DOM objects through the .each() function rather than jQuery objects. Thus, you must wrap the current element within the loop as a jQuery object using $(this).

To simplify handling nested loops involving this, it's advisable to store this in a variable at the start of the function. Consequently, consider updating your function as follows:

$(window).on('resize load', function() {
 $('.listing-box').each(function() {

   var $box = $(this);
   var $thumb = $(this).find('.thumb');

   var boxWidth = $box.width();
   var boxHeight = $box.height();
   var boxAspect = (boxWidth / boxHeight);

   var imgWidth = $thumb.width();
   var imgHeight = $thumb.height();
   var imgAspect = (imgWidth / imgHeight);

   var newWidth,
       newHeight,
       mTop,
       mLeft;

   if (imgAspect < 1) {
    newWidth = boxWidth;
    newHeight = newWidth * imgHeight / imgWidth;
    mTop = (newHeight - boxHeight) / 2;

    $thumb.css({
        width: newWidth + "px",
        height: newHeight + "px",
        marginTop: "-" + mTop + "px"
    });
   } else {
    if (imgAspect > boxAspect) {
        newHeight = boxHeight;
        newWidth = newHeight * imgWidth / imgHeight;
        mLeft = (newWidth - boxWidth) / 2;

         $thumb.css({
            width: newWidth + "px",
            height: newHeight + "px",
            marginLeft: "-" + mLeft + "px"
         });
     } else {
         newWidth = boxWidth;
         newHeight = newWidth * imgHeight / imgWidth;
         mTop = (newHeight - boxHeight) / 2;

         $thumb.css({
             width: newWidth + "px",
             height: newHeight + "px",
             marginTop: "-" + mTop + "px"
         });
     }
 });

});

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

Troubleshooting Issue with Ionic's UI Router

Recently, I created a basic Ionic app to gain a better understanding of UI router functionality. To my surprise, when I ran the app, nothing appeared on the screen. Additionally, the developer tools in Google Chrome did not show any errors or information. ...

Storing additional data from extra text boxes into your database can be achieved using AJAX or PHP. Would you

A dynamic text box has been created using Jquery/JavaScript, allowing users to click on an "Add More" button to add additional input boxes for entering data. However, a challenge arises when attempting to store this user-generated data in a database. Assi ...

The value retrieved by JQuery attr remains constant

Hey everyone, I'm having an issue with getting the ID from a custom attribute using jQuery. When I try to debug, I keep getting the same value each time. I have an HTML table that lists posts from a database using PHP, each with its own specific ID. ...

The popup feature fails to function properly following an Ajax response

Hey there, I've been having trouble getting my jquery popup to work after loading it from ajax. The issue seems to be related to the popup.js code: $(document).ready(function() { $('a.poplight[href^=#]').click(function() { // c ...

Ways to obtain data in JavaScript function from HTML

Struggling to pass the key from a database query in HTML using PHP to a JavaScript function? You're not alone. The challenge lies in passing the field_id to the updateRecords() JS function through the onClick() event of an HTML button. Previously, se ...

Nav bar taking up full width of page, centered to the right with content area

I am facing an issue with aligning my full-width navbar with my fixed content area. The ul keeps changing based on the browser or resolution. Check out this fiddle for reference: http://jsfiddle.net/fwyNy/ subject site CSS Code: #topribbon{ width: 10 ...

sending data from a servlet to ajax

Implementing a star-based voting system involves sending an ajax request to update the database through a servlet when a user casts their vote. This is the ajax code used: $.ajax({ type:'GET', contentType: "charset=utf- ...

Track the number of views each month using PHP and MySQL to generate dynamic jQuery charts

I am currently utilizing jQuery with chart.js to display the view counter based on month using PHP and MySql. Each page view is inserted into MySql in the following format : | id | ip | page | date(timestamp) | | 1 | 138.86.20.20 | test.p ...

Adjust the border hue of the MUI disabled outline input

I am currently struggling to locate the exact definition of this border color. After inspecting the dom, I cannot seem to find any border style within the input component or its pseudo elements... My main goal is to slightly lighten the color of the input ...

Jquery is failing to handle multiple inputs

I am currently working on a system that can handle multiple Yes/No questions. However, every time I try to submit the form, I encounter an error in the console that I cannot identify, and no data is returned from the query. Previously, I used an Array to s ...

show button after the page has finished loading

I have a button similar to this: <input type="submit" id="product_197_submit_button" class="wpsc_buy_button" name="Buy" value="Add To Cart"> However, I am encountering an issue where if the user clicks the button before all scripts are loaded, an e ...

Trouble with Dropdown functionality in Laravel after switching pages

Having an issue here: when the page loads, I have a dropdown menu for language selection which works perfectly fine. However, when I navigate to another page on the site (only works on viewport width less than 1920px), it should appear upon clicking in th ...

The execution of a function in PHP is determined by the data passed from Angular

I've encountered a new challenge while working on web development and would greatly appreciate some assistance. Currently, I have several buttons that need to execute different functions when clicked, such as ng-click='loadA', ng-click=&apos ...

How do I incorporate an external template in Mustache.js?

Welcome, I am a beginner in using Mustache.js. Below is the template and JS code that I have: var template = $('#pageTpl').html(); var html = Mustache.to_html(template, data); $('#sampleArea').html(html); Here is the template ...

Deactivate filtering for the column in the header, while retaining it in the toolbar

I am currently working on implementing a jqGrid table. https://i.stack.imgur.com/d80M8.png My goal is to disable the filter functionality from the header column, while keeping it in the filter toolbar. Is there a way to deactivate the ui-search-input fo ...

What could be causing the position sticky to not function properly in my script?

Can someone help me troubleshoot an issue with the TopOptions image and component sticking to the top of the page? {!categorySearch && ( <div className="max-w-2xl mx-auto z-40 relative overflow-x-hidden font-metropolis_semibold" ...

Issue with IE6: Div inside Anchor element causing inline images to not be clickable links

I am currently facing an issue where I need everything within the anchor tag to be a clickable link, but in IE6 (the only browser I am concerned about at the moment), the inline images are not clickable. I understand that it is not valid HTML to place a di ...

Combining JQuery with ASP.Net

I've been attempting to return a more complex data type in JavaScript, but I seem to be missing something. Can you help me figure out what's wrong? <script language="javascript" type="text/javascript"> ///<Reference Path="~/Script/j ...

Drawing a personalized cursor using JavaScript on a canvas

I've been working on creating a canvas that allows for drawing in vanilla JavaScript. Although I've successfully enabled drawing on the canvas, I'm now looking to implement a feature where a preview dot shows up when the user presses down be ...

steps to receive an event within an AngularJS function

I'm encountering an issue with the event display in this code. <div class="div1" ng-click="displayinfo(event)"> sadfasf </div> $scope.displayinfo = function(event) { alert(event); } Does anyone have a solution for this problem? ...