Is there a way to automatically adjust the positioning of added pins on an image as I scroll through the image?

I have inserted a large image onto my HTML page and to manage its size, I am displaying it within a div that allows for scrolling like a map. Using jQuery, I have placed 3 markers on the image.

The issue I am facing is that when I scroll the image, the markers do not move along with it. How can I resolve this?

Check out my JS Fiddle demo and view the code below:

var Markers = {
  fn: {
    addMarkers: function() {
      var target = $('#image-wrapper');
      var data = target.attr('data-captions');
      var captions = $.parseJSON(data);
      var coords = captions.coords;

      for (var i = 0; i < coords.length; i++) {
        var obj = coords[i];
        var top = obj.top;
        var left = obj.left;
        var text = obj.text;

        $('<span class="marker"/>').css({
          top: top,
          left: left
        }).html('<span class="caption">' + text + '</span>').
        appendTo(target);
      }
    },
    showCaptions: function() {
      $('span.marker').live('click', function() {
        var $marker = $(this),
          $caption = $('span.caption', $marker);
        if ($caption.is(':hidden')) {
          $caption.slideDown(300);
        } else {
          $caption.slideUp(300);
        }
      });
    }
  },

  init: function() {
    this.fn.addMarkers();
    this.fn.showCaptions();
  }
};

$(function() {
  Markers.init();
});
#mydiv {
  overflow: auto;
  max-width: 800px;
  max-height: 600px;
}

#image-wrapper {
  width: 400px;
  height: 400px;
  position: relative;
  margin: 2em auto;
  background: #f6f6f6;
  border: 2px solid #ddd;
}

#image-wrapper img {
  display: block;
  margin: 25px auto;
}

span.marker {
  width: 20px;
  height: 20px;
  background: #f66;
  color: #fff;
  text-align: center;
  position: absolute;
  line-height: 20px;
  cursor: pointer;
}

span.marker:before {
  content: '+';
}

span.caption {
  width: 180px;
  background: #f66;
  color: #fff;
  padding: 4px;
  position: absolute;
  top: 20px;
  left: 0;
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div id="image-wrapper" 
  data-captions='{"coords": [
    {"top":180,"left":160,"text":"iMac 1"},
    {"top":250,"left":300,"text":"iMac 2"},
    {"top":250,"left":360,"text":"iMac 2"}
  ]}'>

  <div id='mydiv'>
    <img src="https://cdn.vectorstock.com/i/1000x1000/96/84/top-view-city-map-abstract-town-flat-design-vector-11299684.jpg" alt="" />
  </div>
</div>

How do I modify my JS Fiddle to ensure that the pins on the image remain sticky in their designated locations even when scrolling?

Answer №1

Is this what you intended to do? You need to place the overflow: auto; in a different location if this is your desired outcome.

var Markers = {
    fn: {
        addMarkers: function() {
            var target = $('#image-wrapper');
            var data = target.attr('data-captions');
            var captions = $.parseJSON(data);
            var coords = captions.coords;

            for (var i = 0; i < coords.length; i++) {
                var obj = coords[i];
                var top = obj.top;
                var left = obj.left;
                var text = obj.text;

                $('<span class="marker"/>').css({
                    top: top,
                    left: left
                }).html('<span class="caption">' + text + '</span>').
                appendTo(target);

            }
        },
        showCaptions: function() {
            $('span.marker').live('click', function() {
                var $marker = $(this),
                    $caption = $('span.caption', $marker);
                if ($caption.is(':hidden')) {
                    $caption.slideDown(300);

                } else {
                    $caption.slideUp(300);

                }

            });

        }
    },

    init: function() {
        this.fn.addMarkers();
        this.fn.showCaptions();

    }
};

$(function() {
    Markers.init();

});
#mydiv {
    max-width: 800px;
    max-height: 600px;
}


#image-wrapper {
    overflow: auto;
    width: 400px;
    height: 400px;
    position: relative;
    margin: 2em auto;
    background: #f6f6f6;
    border: 2px solid #ddd;
}

#image-wrapper img {
    display: block;
    margin: 25px auto;
}

span.marker {
    width: 20px;
    height: 20px;
    background: #f66;
    color: #fff;
    text-align: center;
    position: absolute;
    line-height: 20px;
    cursor: pointer;
}
span.marker:before {
    content: '+';
}

span.caption {
    width: 180px;
    background: #f66;
    color: #fff;
    padding: 4px;
    position: absolute;
    top: 20px;
    left: 0;
    display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div id="image-wrapper" 
<div id="image-wrapper" data-captions='{"coords": [{"top":180,"left":160,"text":"iMac 1"},{"top":250,"left":300,"text":"iMac 2"},
{"top":250,"left":360,"text":"iMac 2"}

]}'>

<div id='mydiv'>
    <img src="https://cdn.vectorstock.com/i/1000x1000/96/84/top-view-city-map-abstract-town-flat-design-vector-11299684.jpg" alt=""/>
    </div>
</div>

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

Aligning multiple items to the right using Flexbox

While it's common knowledge how to align one item to the right in flexbox, what about aligning multiple items, like the last two elements, to the right and the rest to the left? Take a look at this example where I want elements with the class .r to be ...

Utilize resources from webpack's bundled npm package assets

I've been racking my brain over this issue for quite some time now, and I'm starting to wonder if it's even achievable. Any assistance on this matter would be greatly appreciated! The npm dilemma I have an npm package that serves as a coll ...

Avoiding a constantly repeating video to prevent the browser from running out of memory

Using HTML5, I created a video that loops and draws the frames to canvas. I decided to create multiple canvases and draw different parts of the video on each one. However, after some time, I encountered an issue where Google Chrome would run out of memory. ...

How can I access the value of a textbox within a dynamically generated div?

In my project, I am dynamically creating a div with HTML elements and now I need to retrieve the value from a textbox. Below is the structure of the dynamic content that I have created: <div id="TextBoxContainer"> <div id="newtextbox1"> // t ...

Is there a way to adjust this angular2 service to make it slightly more synchronous?

My goal is to create an Angular2 service that performs the following tasks: FTP to a remote server Read certain lines from a file Create a 'results' JSON object and return it to the component that called the service I have successfully impleme ...

NodeJS refuses to import a file that is not compatible with its structure

My website has two important files: firebase.js gridsome-server.js The firebase.js file contains JavaScript code related to Firebase integration: import firebase from 'firebase/app' import 'firebase/firestore' const config = { ap ...

Async/await function chaining within JavaScript for asynchronous operations

const function1 = () => { let isSuccess = false function2( // The function function2 is synchronous and always returns true or false. If the result is true, I want to change the value of isSuccess to true ) return isSuccess } The func ...

What is the method for incorporating a CSRF token into BootstrapTable when using the POST data method?

How can I include a CSRF token in bootstrapTable when using the POST method for data? I am working on a project and trying to add a CSRF token in bootstrapTable. There is some information about CSRF on bootstrap-table.com. Can anyone help me with this iss ...

Issue with backdrop-filter blur effect not functioning correctly

I'm currently utilizing SCSS and within my _header.scss file, I am importing it into my main.scss like so: @use "header"; Here is the snippet of code from my header file (I've removed some less important details such as borders, margin ...

Is it possible to determine the status of a checkbox if it does not contain the "checked" attribute?

I've been struggling to determine the state of a checkbox using Selenium Webdriver or Javascript, and despite extensive research, I still haven't been successful. My issue is: the checkbox does not have a "checked" attribute: <input type="ch ...

Styles are ineffective on the focus property, although they do work before the focus is applied

I'm having trouble changing the font color of the TextInput in material UI. It seems to change to white when I click away, but then reverts back to a purple-ish color (the default) when I focus on it again. I'm not sure what I'm missing here ...

Ways to create a URL path that is not case-sensitive in NextJs using JavaScript

I am currently working on a project using NextJs and I have encountered an issue with URL case sensitivity. The paths fetched from an API all start with a capital letter, causing inconsistency in the URLs. For instance, www.mysite.com/About. I would like t ...

Steps to avoid HTML encoding the ' character in Next.js _document.js file

Currently, I am working on integrating VWO into my website by following the steps mentioned here. I have included the VWO script tag within a NextJs Head tag as shown below: <Head> <script type='text/javascript' id='vwoC ...

Updating and deleting Firebase data from an HTML table: A guide

I am struggling to make the onClick function work in order to update and delete already retrieved data from an HTML table view. Despite trying different approaches, I can't seem to get it right. var rootRef = firebase.database().ref().child("prod ...

What is the best way to display the entire background image in a jumbotron?

After some experimentation, I discovered that by increasing the amount of content I have, it displays the full background image. Is there a clean and efficient way to achieve this? <div class="jumbotron jumbotron-fluid" style="background: url('./a ...

Enhancing Redux efficiency with substantial data structures

I have developed a web application using Redux and React. It is an analytics application that displays a significant amount of data. However, I am facing performance issues as the size of my data store increases. What is the best approach to prevent perfo ...

What causes z-index to be ineffective with sticky elements?

In my website, I've implemented rollover effects in a sticky footer and a responsive menu that stays at the top. However, when the menu is opened and extends over the footer, it covers everything except the rollovers. Closed navigation http://www.mus ...

What is the rationale behind sending only one form?

Is there a way to send two forms with just one click? The first form uploads an image to the server, while the second form sends information to a database. However, only the "myform" seems to be sent. Any suggestions? <form action="uploadpic.php" met ...

Nuxt - issue with updating window innerwidth getter

The class based components in our project utilize a getter to retrieve the window innerWidth. However, I've noticed that the value is only set once and doesn't update if the window width changes. get viewPortWidth() { if (process.client) { ...

Preserve the original position of the inner <div> when animating the container <div> using JQuery

I am currently working on a small website and encountering some challenges with jQuery animation. My issue involves placing a single character text inside a circle and wanting it to grow when the user hovers over it, while keeping the inner text in its ori ...