2

I am having trouble with a piece of code (below and pulled from https://stackoverflow.com/questions/31459832/randomise-and-order-divs-slick-js) which essentially randomises a set of slides for a hero slider (using slick.js). This particular snippet randomises the slides but keeps the last slide in order at the end of the slideshow.

The piece which is confusing me, and the piece which I am sure is pertinent to my problem is the bind/detach/append sequence. What I am aiming for is to keep the first slide in place at the beginning, not the last slide in place at the end. I assume the if statement should be checking for 0, not the array length-1... The confusion for me is, as mentioned, the bind/detach/append.

If anyone can shed some light on the direction i should be heading it would be much appreciated. My Javascript is a little rusty as I am sure you can tell!

Many Thanks in advance.

JJ

$.fn.randomize = function (selector) {
    var $elems = selector ? $(this).find(selector) : $(this).children(),
        $parents = $elems.parent();

    $parents.each(function () {
        $(this).children(selector).sort(function (childA, childB) {
            // * Prevent last slide from being reordered
            if($(childB).index() !== $(this).children(selector).length - 1) {
                return Math.round(Math.random()) - 0.5;
            }

        }.bind(this)).detach().appendTo(this);
    });

    return this;
};



        $('#carousel-hero .carousel-inner').randomize().slick({
            speed: 3000,
            dots: true,
            fade: true,
            autoplay: true,
            autoplaySpeed: 3000,

            prevArrow: '<button type="button" data-role="none" class="carousel-control left slick-prev">Previous</button>',
            nextArrow: '<button type="button" data-role="none" class="carousel-control right slick-next">Next</button>',
        });

    }
Community
  • 1
  • 1
MediaCrush
  • 21
  • 4

1 Answers1

0

What I am aiming for is to keep the first slide in place at the beginning

Instead of writing a weird "randomize" function that almost but not quite randomizes all children of an element, I recommend writing a proper one and making a different part of your code deal with the special requirement of keeping the "first" element in place.

It's important to know that a node in the DOM cannot exist in two places at once. What you append in one location will be removed from where it is now. Therefore there is no need to do any "detach" gymnastics. Simply move nodes by appending them to a new parent - or to the same parent, in random order.

So your task becomes very straight-forward and readable:

$.fn.randomizeChildren = function () {
    var randomOrder = function () {
        return Math.random() - 0.5;
    };
    return this.each(function () {
        $(this).append( $(this).children().sort(randomOrder) );
    });
};

$("#randomize").click(function () {
    $("ul.random").randomizeChildren().prepend(function () {
        return $(this).find(".first");
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<table>
  <tr><td>
    <ul class="random">
      <li class="first">1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li>
    </ul>
  </td><td>
    <ul class="random">
      <li class="first">1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li>
    </ul>
  </td></tr>
</table>

<button id="randomize">Randomize</button>
Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • Have deleted the answer as you suggested. How should I communicate my question in future? Should I ask another question on the main board? – MediaCrush Aug 16 '16 at 13:54
  • Basically, yes. But pay attention not to create "fake forum thread" by referring to an older question of yours, requiring your readers to go and understand *that* first. StackOverflow is for asking self-contained questions that provide all the context that is necessary to understand and answer them. Ideally your first question is fleshed out enough so that an answer does not lead to "but now I get different errors" response, which quickly devolves into an interactive debugging session that provides virtually no value for any future visitor of the thread. – Tomalak Aug 16 '16 at 13:58
  • I am confused. How am I meant to ask for help with an answer without referring to my original question. I could have pasted the code from the entire page, but that would probalby be even more annoying, no? Sorry to sound like a useless noob. – MediaCrush Aug 16 '16 at 14:03
  • You are meant to think about your question and ask it in a way that can be answered, plain and simple. *"I have A, how can I do B with it?"* - *some people come and show ways of doing B* - end of story. I presume you have come to StackOverflow in the past as a reader and found useful answers to your problems quickly. The only reason why that is possible is because StackOverflow *explicitly* does not work like a forum. No follow-ups, no discussion, as few purely opinion-based posts as possible. – Tomalak Aug 16 '16 at 14:08
  • Never mind, at least you care. Most new users don't. The ideal question contains an [MCVE](http://stackoverflow.com/help/mcve). You are not supposed to post your entire code. Nobody wants to read 250 of lines mostly irrelevant stuff - I mean, from a reader's perspective, you wouldn't, would you? Condense. Strip any useless complexity. Try to flesh out the core problem(s). Ask a separate question for the secondary problems (unless you find solutions for them first, of course). Sounds like hard work? It is. A question that incites full-blown follow-ups is not well thought-out. – Tomalak Aug 16 '16 at 14:16
  • Final remark: That isn't to say that you should not ask follow-ups or clarify details in the comments. — If an answer to a question increases your understanding of the problem, but new ones come up, then use that new understanding to create a new self-contained question. No need for cross-references. You can make them, but don't make them in a way that requires anyone to read all that just to understand your question. — If an answer almost works and some detail is unclear, write comments. Try to get closure on the question *as it was asked*, not on the moving target that your code is. – Tomalak Aug 16 '16 at 14:29
  • So, back to the question itself: I understood it as *"I want to randomize the order of child nodes in an element, but keep the first node at the top"*, and that's what my answer does (my answer contains an MCVE, a runnable one, even). As far as I can see, anything related to `slick` falls into the category of "useless complexity" that can be stripped away without changing the core problem, so I ignored that bit. – Tomalak Aug 16 '16 at 14:35
  • I mentioned slick as i thought it may well be relevant to the answer. It is quite likely that my knowledge (or lack thereof) when it comes to javascript may have casued me to think this was relevant. You are right, however, that with regards to your answer it is not relevant. – MediaCrush Aug 16 '16 at 14:54
  • At least I could not see the relevance. Maybe it is, but that's part of fleshing out the question. Making a runnable code sample that uses slick and reproduces your problem greatly increases the chance of getting an answer that uses slick and solves your problem. ;) – Tomalak Aug 16 '16 at 14:58