Jquery On Change Not Functioning

- 1 answer

Currently I have html like this:

<div class="selector-wrapper">
    <label for="product-select-1372104458328-option-0">Style</label><select class="single-option-selector" data-option="option1" id="product-select-1372104458328-option-0">
        <option value="Adjustable">
        <option value="Flex Fit">
            Flex Fit
        <option value="Trucker Hat">
            Trucker Hat

my jquery code is this:

$(function() {
    $('.single-option-selector').on('change', function() {
    console.log( 'blahblah' );

the expected result would be for there to be a console.log when the option changes in .single-option-selector however that is not the case I get nothing. No error or anything. Any ideas what I'm doing wrong?



As you have mentioned that the markup is generated by Shopify, it is very likely that the <select> element you are choosing is actually unavailable at runtime (i.e. it has not been injected in the DOM yet). In this case, jQuery fails silently when it cannot find the element to bind event handlers to. You can run a simple check by plugging this line in:


My suspicions are confirmed if it returns 0, which means at runtime your script cannot find the relevant element in your DOM. The way to overcome this is by using event bubbling: basically you attach an event handler to a pre-existing element at runtime, and simply filter the event so that you only catch those emitted by elements identified with your selector, i.e.:

$(document).on('change', '.single-option-selector', function () {
    // Your logic here

However, this approach has a drawback: there is a significant overhead by listening to events on the top level document. If you know that there is an element that is always available at runtime, let's say the given DOM structure:

    <!-- This element is always present at runtime -->
    <section id="content">
        <!-- Contains dynamically injected HTML -->

Then you can update your selector to listen to events bubbling up to #content and not further up:

$('#content').on('change', '.single-option-selector', function () {
    // Your logic here