1

I am applying a series of list-items a background-image from an array of images.

I have created an array of images 'artifacts' :

var artifacts = [
  '/img/artifacts/artifact-1.svg',
  '/img/artifacts/artifact-2.svg',
  '/img/artifacts/artifact-3.svg',
  '/img/artifacts/artifact-4.svg',
  '/img/artifacts/artifact-5.svg',
  '/img/artifacts/artifact-6.svg',
  '/img/artifacts/artifact-7.svg'
];

HTML markup looks like this.

<ul class="slick-dots">
  <li>1</li>
  <li>2</li>
  <li class="slick-active">3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
  <li>7</li>
  <li>8</li>
  <li>9</li>
</ul>

There is a 'selected' set of images for the hover/selected colour.

var artifactHover = [
  '/img/artifacts/artifact-1-hover.svg',
  '/img/artifacts/artifact-2-hover.svg',
  '/img/artifacts/artifact-3-hover.svg',
  '/img/artifacts/artifact-4-hover.svg',
  '/img/artifacts/artifact-5-hover.svg',
  '/img/artifacts/artifact-6-hover.svg',
  '/img/artifacts/artifact-7-hover.svg'
];

And here is my JavaScript this far:

 $('.slick-dots li').css('background-image', function(i) {
    return 'url("' + artifacts[i % artifacts.length] + '")';
  });
  $('.slick-dots .slick-active').css('background-image', function(i) {
    return 'url("' + artifactHover[i % artifactHover.length] + '")';
  });


  $('.slick-dots li button').click(function() {

    $('.slick-dots li').css('background-image', function(i) {
      return 'url("' + artifacts[i % artifacts.length] + '")';
    });

    var index = $(this).parent().index();

    $(this).parent().css('background-image', function(i) {
      return 'url("' + artifactHover[index] + '")';
    });

  });

So when user clicks a list item, it pulls the appropriate image from the array based off the element that was clicked.

If there are more list-items than there are images then it will just start over and start from the beginning again. My issue is matching the current selected list-item with the appropriate hover image. By using the index() for the artifact-hover, if I select a list item that is larger than the amount in the array of images it places a blank image in instead of restarting from the beginning of list.

4
  • 2
    Have you tried this: artifactHover[index%artifactHover.length] ? Commented Jan 4, 2017 at 20:47
  • @Alexandru-IonutMihai YES! Thank you! Sorry, i'm still confused with how the % works Commented Jan 4, 2017 at 20:55
  • @h0bb5 That is a modulo. It does the remainder. So 2 % 3 = 2 or 7 % 3 = 1. 7 / 3 = 2 but we have 1 remaining. Commented Jan 4, 2017 at 21:01
  • @h0bb5, % is used to get the remainder after integer division.Suppose you have 5 images, and 7 li elements. For first li ->first image, second li -> second image,...for 5th li->5th image, for 6th image it will be -> 6%5 which equals to 1. So for 6th 'li' -> first image, and 7th li will be 7%5 image which means 2. Hope this helps. Commented Jan 4, 2017 at 21:04

2 Answers 2

3

All you need is to use this,in order to start from the beginning again.

artifactHover[index%artifactHover.length]
Sign up to request clarification or add additional context in comments.

Comments

0

Not sure what the issue with your script is , but theres an easier way to write it.

Just use the jQuery foreach to get the index and the element and a temporary variable to build the URL string before passing it to jQuery.css()

var artifacts = [
  '/img/artifacts/artifact-1.svg',
  '/img/artifacts/artifact-2.svg',
  '/img/artifacts/artifact-3.svg',
  '/img/artifacts/artifact-4.svg',
  '/img/artifacts/artifact-5.svg',
  '/img/artifacts/artifact-6.svg',
  '/img/artifacts/artifact-7.svg'
];



var artifactHover = [
  '/img/artifacts/artifact-1-hover.svg',
  '/img/artifacts/artifact-2-hover.svg',
  '/img/artifacts/artifact-3-hover.svg',
  '/img/artifacts/artifact-4-hover.svg',
  '/img/artifacts/artifact-5-hover.svg',
  '/img/artifacts/artifact-6-hover.svg',
  '/img/artifacts/artifact-7-hover.svg'
];

/* each function can take two parameters:  i for index and elem for the actual DOM element */
$(".slick-dots li").each(function(i, elem) {



  var tmp_url = "url('" + artifacts[i % artifacts.length] + "')";

  /* set custom property on element to grab non-clicked image */

  $(elem).prop("fallback", tmp_url);

  /*  set the image */
  $(elem).css("background-image", tmp_url);

  /*  add event listener for the click event to the element  and function call-back */
  $(elem).on("click", function() {
    /*  use each again   to change all backgrounds except current one */

    /* use .prop() to grab the custom property */
    $(".slick-dots  li").each(function(u, elem2) {
      $(elem2).css("background-image", $(elem2).prop("fallback"));

    });

    /* use a new variable for the currently clicked one so they don't cause collision */
    var tmp_url2 = "url('" + artifactHover[i % artifactHover.length] + "')";

    $(elem).css("background-image", tmp_url2);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="slick-dots">
  <li>1</li>
  <li>2</li>
  <li class="slick-active">3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
  <li>7</li>
  <li>8</li>
  <li>9</li>
</ul>

EDIT

In the snippet I added in the .prop() assignment of a fallback property for each li element, so that when an element is clicked, each li element can properly return to its assigned value.

Below is the non-comment version of the Javascript code

var artifacts = [
  '/img/artifacts/artifact-1.svg',
  '/img/artifacts/artifact-2.svg',
  '/img/artifacts/artifact-3.svg',
  '/img/artifacts/artifact-4.svg',
  '/img/artifacts/artifact-5.svg',
  '/img/artifacts/artifact-6.svg',
  '/img/artifacts/artifact-7.svg'
];



var artifactHover = [
  '/img/artifacts/artifact-1-hover.svg',
  '/img/artifacts/artifact-2-hover.svg',
  '/img/artifacts/artifact-3-hover.svg',
  '/img/artifacts/artifact-4-hover.svg',
  '/img/artifacts/artifact-5-hover.svg',
  '/img/artifacts/artifact-6-hover.svg',
  '/img/artifacts/artifact-7-hover.svg'
];

$(".slick-dots li").each(function(i, elem) {
  var tmp_url = "url('" + artifacts[i % artifacts.length] + "')";
  $(elem).prop("fallback", tmp_url);
  $(elem).css("background-image", tmp_url);
  $(elem).on("click", function() {
    $(".slick-dots  li").each(function(u, elem2) {
      $(elem2).css("background-image", $(elem2).prop("fallback"));
    });
    var tmp_url2 = "url('" + artifactHover[i % artifactHover.length] + "')";
    $(elem).css("background-image", tmp_url2);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="slick-dots">
  <li>1</li>
  <li>2</li>
  <li class="slick-active">3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
  <li>7</li>
  <li>8</li>
  <li>9</li>
</ul>

8 Comments

This is written more efficiently! However it does not remove the 'artifact-hover' when another element is clicked, it only adds 'artifact-hover'.
seee edit i added a line that uses the .not() functionality along with a simple selector
Hey Mike, something seems to have been broken from this change. It does add the selected-hover image and remove it from the last, but it it is applying the same image to all of the list items each click and the image across all elements when a new one is selected. Thank you for your help so far!
change the line below it from tmp_url = to var tmp_url2 =
sorry, im not sure which line you are referring to? line below what
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.