0

The issue I am having involves two objects which are supposed to have a function bound to them once the page loads.

One of the objects is a widget loading via a script. The widget is eventually placed in the div. The other object is pure html, which works as expected.

I am assuming this is an issue with the order the objects are loading, but I can't seem to come to a solid conclusion since my script to build the div is in the head (so it should load first?), followed by the html, and finally the script at the bottom of my document. So if this is all true, the object should be loaded before the final $(document).ready function runs, but the bind does not seem to be applied to the generated div.

Any help would be greatly appreciated and will receive a fast response! (I promise!!!)

<script type="text/javascript" id="BROKEN_OBJECT" src="https://link.com/broken.js"></script>    //(In Head)

<div>
    <span /> Object to be loaded via JS
</div>
<div class="widget">
    <ul class="hs">
        <li>
            <div>
                <span /> Object loaded via HTML
            </div>
        </li>
    </ul>
</div>
jQuery(function ($) {
    $.fn.hScroll = function (amount) {
        amount = amount || 120;
        $(this).bind("DOMMouseScroll mousewheel", function (event) {
            var oEvent = event.originalEvent,
                direction = oEvent.detail ? oEvent.detail * -amount : oEvent.wheelDelta,
                position = $(this).scrollLeft();
            position += direction > 0 ? -amount : amount;
            $(this).scrollLeft(position);
            event.preventDefault();
        })
    };
});

$(document).ready(function () {
    $('.hs').hScroll(60); // You can pass (optionally) scrolling amount
});

EDIT I've created a new version of the code which includes almost everything.

<!doctype html>
<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <script type="text/javascript" id="BROKEN_OBJECT" src="https://link.com/broken.js"></script>
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>

    <title>Events Scroll</title>
    <style>
        .widget {
            padding: var(--gutter) 0;
            display: grid;
            grid-gap: var(--gutter) 0;
            grid-template-columns: var(--gutter) 1fr var(--gutter);
            align-content: start;
            --gutter: 20px;
            padding-left: 50px;
            padding-right: 50px;
        }

        .widget > * {
            grid-column: 2 / -2;
        }

        .widget > .full {
            grid-column: 1 / -1;
        }

        .hs {
            display: grid;
            grid-gap: calc(var(--gutter) / 2);
            grid-template-columns: 0px;
            grid-template-rows: 285px;
            grid-auto-flow: column;
            grid-auto-columns: 200px;
            overflow-x: scroll;
            scroll-snap-type: x proximity;
            padding-bottom: calc(.75 * var(--gutter));
            margin-bottom: calc(-.25 * var(--gutter));
        }

        .hs:before,
        .hs:after {
            content: '';
            width: 10px;
        }

        ul {
            list-style: none;
            padding: 0;
        }

        .widget {
            width: 100%;
            height: 100%;
        }

        .hs > li,
        .event {
            transform: scale(.96);
            scroll-snap-align: center;
            display: flex;
            flex-direction: column;
            align-items: center;
            background-color: rgb(240, 240, 240);
            border-radius: 8px;
            border: solid 1px gray;
            background-repeat: no-repeat;
            height: 285px;
            background-size: 200px 200px;
        }
    </style>

</head>
<body>

    <div class="lwcw" data-options="id=3&format=html"></div>

    <div class="widget">
        <ul class="hs full no-scrollbar" id="scroll">
            <li class="event" style="background-image: url({image_src})">
            </li>
            <li class="event" style="background-image: url({image_src})">
            </li>
            <li class="event" style="background-image: url({image_src})">
            </li>
            <li class="event" style="background-image: url({image_src})">
            </li>
            <li class="event" style="background-image: url({image_src})">
            </li>
            <li class="event" style="background-image: url({image_src})">
            </li>
            <li class="event" style="background-image: url({image_src})">
            </li>
            <li class="event" style="background-image: url({image_src})">
            </li>
            <li class="event" style="background-image: url({image_src})">
            </li>
            <li class="event" style="background-image: url({image_src})">
            </li>
            <li class="event" style="background-image: url({image_src})">
            </li>
            <li class="event" style="background-image: url({image_src})">
            </li>
        </ul>
    </div>


    <script>

        $('.widget').on("DOMMouseScroll mousewheel", '#scroll', function (event) {
            amount = 60
            var oEvent = event.originalEvent,
                direction = oEvent.detail ? oEvent.detail * -amount : oEvent.wheelDelta,
                position = $('#scroll').scrollLeft();
            position += direction > 0 ? -amount : amount;
            $('#scroll').scrollLeft(position);
            event.preventDefault();
        });

    </script>


</body>
</html>
  • Your widget should have a load callback you can leverage, otherwise the only recourse is an interval function to check for the element periodically. – isherwood Mar 10 '21 at 19:21
  • 1
    *[Your] script is in the head* / *at the bottom of [your] document* - but they both use doc.ready so will only run when doc loaded (doc ready) regardless of where it is placed in the code. Your first `$.fn.hScroll=` can be defined at any time after jquery loaded, it doesn't need to be (nor should be) in doc.ready – freedomn-m Mar 10 '21 at 19:50
  • `$('.hs').hScroll(60);` will applie on all existing `.hs` elements on page load. Elements created after page load (which is unclear how in your question) will need to have that function call too. How to call it depends on how they are created. – Louys Patrice Bessette Mar 10 '21 at 19:52
  • 1
    Note that [bind](https://api.jquery.com/bind/) was deprecated in v3.0 (some time ago (2016)) so you should probably use `.on` - in which case you can change to use event delegation - but perhaps not so easy as you've put it inside a wrapper instead of binding directly. – freedomn-m Mar 10 '21 at 19:54
  • Duplicate (I'm 90% sure): https://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements – Louys Patrice Bessette Mar 10 '21 at 19:55
  • @LouysPatriceBessette I agree that it looks like it needs some form of event delegation, but not sure how without rewritting - given the `$.fn.hScroll` and `$(selector).hScroll` - could be refactored to allow for a selector, but not as a jquery plugin in the form `$.fn.X` – freedomn-m Mar 10 '21 at 20:15
  • Well... If possible to see where the elements are appended to DOM after page load. Just call the `.hScroll(60)` on it right after... In a callback or something. Nothing we can tell from actual OP code. Making it *"Need more details"*... – Louys Patrice Bessette Mar 10 '21 at 20:19
  • 1
    I believe I found a work around, which should work but isn't. I think I may be having another issue with some css styling, preventing my widget from actually scrolling. I will update the post with new information soon. – Chris Petraskie Mar 10 '21 at 20:30

0 Answers0