What is the method for adding an event listener in AngularJS within an ng-repeat iteration?

I'm completely new to AngularJS and currently working on building a photo gallery. The basic idea is to have an initial page displaying thumbnail photos from Twitter and Instagram using an AngularJS ng-repeat loop. When a user hovers over an image, I want it to fade with a button for interaction. However, there seems to be an issue as the hover effect affects all images instead of just the one being hovered over. I've used ng-mouseenter and ng-mouseleave for this functionality, but it's not behaving as expected. Any help to troubleshoot this would be highly appreciated! Below is the code snippet along with a link to view it online: Check out the demo here

<style>
        * {
            box-sizing: border-box;
            font-family: sans-serif;
        }
        h1, 
        h2{
            margin-left:10px;
        }
        /* Styles omitted for brevity */
    </style>

<body>
   <!-- Code snippet to showcase the issue goes here -->
</body>

<script>
    // JavaScript logic for handling the functionality
</script>

Hello everyone, I received great assistance from Aaron earlier regarding my project. However, I stumbled upon another challenge while developing the light-box feature for the app. When clicking on the 'VIEW' button, the overlay displays only the first image in the collection regardless of which image was clicked. This seems to be another problem related to the ng-repeat function. Each object contains the main image URL at x.mainImage.url, which should be accessed through the ng-repeat loop with x.mainImage.url. Unfortunately, the implementation isn't working as intended. Any suggestions or guidance on how to fix this issue would be immensely helpful. Here's the relevant code snippet below and you can also check it out online: View the demo here

<style>
    * {
        box-sizing: border-box;
        font-family: sans-serif;
    }
    h1, 
    h2{
        margin-left:10px;
    }
    /* Additional styles are included */
  </style>

 <body>
<!-- Revised code block showcasing the issue -->
 </body>

  <script>
    // Custom JavaScript functions to control the light-box behavior.
  </script>

Answer №1

While you inquired about implementing this the Angular way, it's essential to note that ng-mouseenter and ng-mouseleave come with high performance costs. In a real-world application, it is recommended to handle these interactions using CSS.

Let me demonstrate how to resolve the issues in your approach and provide you with a more efficient CSS solution :)

In this scenario, the $index variable proves to be valuable as it can be utilized within an angular template under an ng-repeat tag to capture the index of the current data item being looped through. You should utilize this variable to store the index of the currently hovered item in the controller scope. Subsequently, when the mouse moves away from the item, you can discard the stored index.

When applying styles, leverage a ternary operator to assign active or inactive styles based on whether the item's index matches the saved active index variable on the scope.

In case you are unfamiliar, a ternary expression serves as a concise form of a conditional statement i.e.,

conditional_expression ? value_returned_if_true : value_returned_if_false
. It offers a succinct means of crafting conditional statements in javascript (or an angular template which interprets javascript in this instance).

For this demonstration, I combine a ternary expression with saving the index of the last item entered by the mouse to allocate hover or non-hovered styles to each item.

This is an abbreviated version mimicking your example:

Angular controller:

app.controller('exampleController', function($scope) {
  $scope.overlayColorStyles = { "opacity": 0 };
  $scope.overlayTextStyles = { "opacity": 0 };
  $scope.overlayTextStylesActive = { "opacity": 1 };
  $scope.overlayColorStylesActive = { "opacity": .75 };
  $scope.activeItemIndex = null;
});

Template:

<div id="outer" class="outer">
  <div class="inner"
      ng-mouseenter="$scope.activeItemIndex = $index"
      ng-mouseleave="$scope.activeItemIndex = null"
      ng-repeat="x in insideData">
      <img ng-if="x.service=='Instagram'||(x.service=='Twitter' && x.mediaType=='image')" ng-src='{{x.thumbnails[0].url}}'>
      <div ng-if="x.service=='Twitter'&& x.mediaType!='image'" class="outer-caption"><div class="inner-caption">{{x.caption}}</div></div>
      <div class="overlay-color"
        ng-style="$scope.activeItemIndex === $index ? overlayColorStylesActive : overlayColorStyles">
      </div>
      <div class="overlay-text"
        ng-style="$scope.activeItemIndex === $index ? overlayTextStylesActive : overlayTextStyles">
        VIEW
      </div>
  </div>
</div>

It should be noted that this code should mainly serve as a learning exercise. Angular's primary role does not involve styling based on user interactions. Attempting to do so may significantly slow down your application, especially with an increasing number of items. Utilizing CSS for this purpose will result in notably better performance :)

CSS alternative below:

html:

<div id="outer" class="outer">
  <div class="inner"
      ng-repeat="x in insideData">
      <img ng-if="x.service=='Instagram'||(x.service=='Twitter' && x.mediaType=='image')" ng-src='{{x.thumbnails[0].url}}'>
      <div ng-if="x.service=='Twitter'&& x.mediaType!='image'" class="outer-caption"><div class="inner-caption">{{x.caption}}</div></div>
      <div class="overlay-color"></div>
      <div class="overlay-text">VIEW</div>
  </div>
</div>

CSS:

.overlay-color {
  opacity: 0.0;
}

.overlay-text {
  opacity: 0.0;
}

.inner:hover .overlay-text {
  opacity: 1.0;
}

.inner:hover .overlay-color {
  opacity: 0.75;
}

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

Issue with menu height persisting while resizing screen

For my responsive design project, I am implementing a menu that switches to a menu button when the width is less than or equal to 768px. Currently, I am using jQuery to dynamically adjust the height of the menu when the menu button is clicked. The jQuery ...

Refresh DataTable while making a fetch request

Here is the HTML code snippet where I want to apply DataTable: <div id="reportrange" style="background: #fff; cursor: pointer; padding: 5px 10px; border: 1px solid #ccc;"> <span></span> </div> <table id=" ...

Implementing Object Value Assignment to an Element Using jQuery

I recently received a set of data via an API request: https://i.stack.imgur.com/YGe2D.jpg In order to display this data as selectable options, I included the following code snippet in my AJAX script: $.each($(value.routes), function(index, route){ $ ...

Showing attributes of models using Sequelize and Handlebars

As a novice in the world of programming, I am currently immersed in a website project where users can write and post articles. One crucial aspect I am focusing on is displaying the history of articles written by each user on their account page. Despite uti ...

Showing a div element with the power of JavaScript

I want to enhance the accessibility of my website for users who do not have JavaScript enabled. Content that will be visible if the user has JavaScript enabled. Content visible when JavaScript is disabled. By default, DisableJS is set to Display:none; ...

Are the references to clip-path: path() on MDN and other sources inaccurate?

I'm attempting to achieve a simple task by using clip-path with the path property and having it scale to fit the entire size of the containing div. After researching extensively, I came across mentions of the [geometry-box] property in some places, bu ...

How to disable the Rubber/Elastic scrolling feature on your iPad?

On my webpage, there is a combination of vertical and horizontal scrolling. Everything works fine when the user swipes left or right exactly, but issues arise when the swipe is not precise along a straight line (diagonally). In this case, both vertical and ...

Problem with flags series in Highcharts/Highstock

Can anyone help me figure out why not all the flags in the withdrawals series are displaying? For reference, you can view the following JS fiddle: https://jsfiddle.net/lucianpurcarea/5zxa0jsm/13/ The snippet of code below is responsible for creating the d ...

Verify in JavaScript if the script is executing within a WinStore (WinJS) program

I am in the process of developing a JavaScript library that is compatible with both Windows Store (WinJS) applications and traditional HTML/JavaScript apps. The dependency I am utilizing loads dynamically and has separate SDKs for WinJS apps and standard w ...

Utilize the composition API in Vue.js 3 to call a function and pass in a parameter

I'm having trouble calling a function from another component. When I click on a button in my parent component, formTelemarketing(), it should send data to my other component nAsignedCalls() and call the function getCalls(param) in that component. Thi ...

Experiencing a hiccup while attempting to query the Twitter API using Node.js

I am a beginner exploring the world of node.js, but I keep encountering a perplexing "write after end" error. Despite searching for solutions online, none seem to address my specific issue. My current project involves querying the Twitter API. req.on(&apo ...

Modify input value using jQuery upon moving to the next step

When you type into an input[text] and press the tab button, it automatically moves to the next input. If you fill out all the inputs and then want to re-fill them, the values will be highlighted in blue. However, I wanted to achieve this without having to ...

Showing Text Information from a distant web server's jQuery.getJSON() script

I am currently working on a personal project that involves displaying data from a remote server. The HTML code I am using looks like this: <script> jQuery.getJSON("http://someurl.com/something.cgi? AJZ=1&STOCK=S", function(data) { if (data.inform ...

I have received a JSON multi-line string after entering information in a textarea

I've been working on a small social network project where users can create and share posts. However, I encountered an issue with formatting when storing and displaying the posts. When a user enters text with line breaks in the post creation form, it ...

When attempting to run the npm install mathjs command, an error is displayed

Trying to install mathjs using npm but encountering an error: npm install mathjs The error message received is as follows: npm WARN tar TAR_ENTRY_ERROR UNKNOWN: unknown error, write npm WARN tar TAR_ENTRY_ERROR UNKNOWN: unknown error, write npm WARN tar T ...

jQuery mobile collapsed list view is not functioning correctly when used with search feature

I have successfully implemented a listview in jquery with a listdivider that includes a filter function. The search feature works perfectly, however, when collapsing either of the list dividers, the search functionality stops working altogether. <!DOCT ...

Utilizing query parameters as variables in rewrites with Next.js

My goal is to use Next JS to redirect requests from /home?id=123qwert to the new path of /home/123qwert. I'm struggling with extracting the query parameter from the source and using it in the destination. This is what I have attempted so far: as ...

NodeJS/express: server became unresponsive after running for some time

Initially, my service using express and webpack ran smoothly. However, I started encountering an issue where the server would hang with no message code being received, as shown in the server message screenshot (server message screenshot). This problem kept ...

Sorry, we couldn't locate the API route you are looking for

Within my Next.js project resides the file main/app/api/worker-callback/route.ts: import { NextApiResponse } from "next"; import { NextResponse } from "next/server"; type ResponseData = { error?: string }; export async function PO ...

A step-by-step guide on leveraging ethereumjs-tx within a web browser

Is it necessary to install npm ethereumjs-tx when utilizing the browser-based version downloaded directly from GitHub? If so, how can we incorporate the ethereumjs-tx module into our script file? It seems like these are two separate components based on ...