Turbolinks prohibiting Javascript appended class for background images

放肆的年华 提交于 2019-12-11 17:49:00

问题


I am integrating a front end html theme with a Laravel app and I am running into an issue with turbolinks not allowing Javascript to append div classes. This is causing the background images to only be displayed on refresh.

<div class="intro-banner" data-background-image="/storage/images/hero.jpg">
    <div class="container">

custom.js

/*----------------------------------------------------*/
/*  Inline CSS replacement for backgrounds
/*----------------------------------------------------*/
function inlineBG() {

    // Common Inline CSS
    $(".single-page-header, .intro-banner").each(function() {
        var attrImageBG = $(this).attr('data-background-image');

        if(attrImageBG !== undefined) {
            $(this).append('<div class="background-image-container"></div>');
            $('.background-image-container').css('background-image', 'url('+attrImageBG+')');
        }
    });

} inlineBG();

// Fix for intro banner with label
$(".intro-search-field").each(function() {
    var bannerLabel = $(this).children("label").length;
    if ( bannerLabel > 0 ){
        $(this).addClass("with-label");
    }
});

// Photo Boxes
$(".photo-box, .photo-section, .video-container").each(function() {
    var photoBox = $(this);
    var photoBoxBG = $(this).attr('data-background-image');

    if(photoBox !== undefined) {
        $(this).css('background-image', 'url('+photoBoxBG+')');
    }
});

回答1:


It looks like this code is only run once: on the initial page load. To get it working for every page load, you will need to run it on turbolinks:load. As the script also appends elements to the page, you need to be careful that you don't end up with unnecessary duplicate elements. Turbolinks stores a copy of the page in its final state before a visitor navigates away. This cached copy will include any appended HTML. So be sure your code checks for the presence of the appended elements before appending, or remove the elements before they are cached.

The following takes the latter approach, by removing elements on turbolinks:before-cache:

/*----------------------------------------------------*/
/*  Inline CSS replacement for backgrounds
/*----------------------------------------------------*/

$(document).on('turbolinks:load', function () {
    $(".single-page-header, .intro-banner").each(function() {
        var attrImageBG = $(this).attr('data-background-image');

        if(attrImageBG !== undefined) {
            $(this).append('<div class="background-image-container"></div>');
            $('.background-image-container').css('background-image', 'url('+attrImageBG+')');
        }
    });

    // Fix for intro banner with label
    $(".intro-search-field").addClass(function () {
        if ($(this).children("label").length) return "with-label";
    });

    // Photo Boxes
    $(".photo-box, .photo-section, .video-container").css('background-image', function () {
        return 'url('+$(this).attr('data-background-image')+')'
    })
});

$(document).on('turbolinks:before-cache', function () {
    $(".single-page-header, .intro-banner").each(function() {
        $(this).children(".background-image-container").remove();
    });
});

I have also tidied up some of the jQuery code. Many jQuery functions accept functions as arguments, which simplifies things somewhat, and removes the need to iterate over a jquery selection with each.

Finally, wrapping lots of snippets in $(document).on('turbolinks:load', function () {…} is not great practice as creates a dependency on Turbolinks, and if you ever decided to move to something else, you have to update every place where this is called. If you're feeling adventurous, you may want to create a mini-framework like the one I create here: https://stackoverflow.com/a/44057187/783009



来源:https://stackoverflow.com/questions/51850497/turbolinks-prohibiting-javascript-appended-class-for-background-images

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!