Solution 1 :

You can do the not(this) as you showed originally, and then update the data-position on them. Then update the data-position on the one clicked, at some point, to 1.

var $images = $('img').on('click', function(){
  $images.not(this).attr('data-position', function(index){
    return index + 2;
  $(this).attr('data-position', 1);
<script src=""></script>
<div class="parent">
  <img data-position="1" src="" alt="one">
  <img data-position="2" src="" alt="two">
  <img data-position="3" src="" alt="three">
  <img data-position="4" src="" alt="four">

Solution 2 :

Check out this fiddle:

Here’s the important code:

var imgs = $('div.parent > img')
imgs.on('click', function(index) {
    $(this).attr("data-position", "1");
    var otherElements = imgs.not(this);
    otherElements.each(function(index) {
        $(this).attr("data-position", index+2);

    // Optionally, uncomment the next 3 lines to output the data-positions
    //$(imgs).each(function(index) {
    //  console.log(index, $(this).attr("data-position"));

Solution 3 :

My solution involves setting the event listener on the parent so that it’s easier to query and manipulate its children. The elements that came before the clicked target will ‘wrap’ and continue the numbering from where the last element in the array left of.

const $parent = $('.parent');
const $children = $parent.children();
const childrenLength = $children.length;
$parent.on('click', e => {
  const clickedIndex = $children.index(;
  let rearange = 1;
  $children.each((i, el) => {
    if (i < clickedIndex) {
      el.dataset.position = (childrenLength - clickedIndex + 1) + i;
    } else {
      el.dataset.position = rearange++;

Running example: jsfiddle

Problem :

This is my markup

<div class="parent">
  <img data-position="1" src="">
  <img data-position="2" src="">
  <img data-position="3" src="">
  <img data-position="4" src="">

When any of the img elements clicked, the clicked element needs to have its data-position set to 1 and the rest of elements should follow with data-position="2" and so on. To achieve this I can’t append or rearrange elements, since this will have no effect.

This is what I have tried. I thought, why not get all them not(this) elements put the through the loop and assign data attributes.

var img = $('img')
img.on('click', function() {
    var otherElements = img.not(this).length;

This piece of code works right the first time, but on the second lick I get different results.


Comment posted by Marc

I don’t see where you’re doing any assignment of a

Comment posted by Taplar

Do you want to renumber everything, or is it enough to just swap the current number one to be the one clicked.

Comment posted by ivan marchenko

While looping, the first time around I get 3 (which is correct), then if I click one more time I get 2, which is not correct.

Comment posted by ivan marchenko

@Taplar, yes I need to renumber everything.

Comment posted by user3154108

Do the numbers need to wrap? Like is the first element going to get data-position=4 of the first click is elsewhere?


Leave a Reply

Your email address will not be published. Required fields are marked *