Создание настраиваемого элемента с использованием shadow dom для CSS и Bootstrap 4

Я пытаюсь разработать собственный компонент, использующий всплывающее окно Bootstrap 4. В основном я хочу создать плавающую кнопку с настраиваемым CSS, на который не влияет CSS страницы, и убедиться, что при нажатии на кнопку отображается всплывающее окно Bootstrap (также настраиваемое). Я прочитал это предыдущее обсуждение, в нем были мне полезны до определенного момента ... Как я могу продолжить?

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css">
    <title>fwa-button</title>
</head>
<body>

    <div class="container-fluid">
        <fwa-button></fwa-button>
    </div>


    <script src="fwa-button.js"></script>
    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
    <script>
        $(function () {
            $('[data-toggle="popover"]').popover({
                container: 'body',
                html: true,
                placement: 'top',
                title: '',
                content: function() {
                    let message = '<p class="h5">Ciao, come posso esserti d\'aiuto?<p>';
                    let checkbox = '<div class="custom-control custom-checkbox"><input type="checkbox" class="custom-control-input" id="customCheck1"><label class="custom-control-label" for="customCheck1">Confermi di aver preso visione della normativa vigente sul trattamento dei dati personali.</label></div>';

                    return message + checkbox;
                },
                template: '<div class="popover chatbox-popup" role="tooltip"><header class="chatbox-popup__header"><aside style="flex:3"><i class="fa fa-user-circle fa-4x chatbox-popup__avatar" aria-hidden="true"></i></aside><aside class="ml-3" style="flex:8"><h1 class="live-chat">Pinco Pallino</h1> <em>Venditore (Online)</em></aside><h3 class="popover-header"></h3></header><div class="popover-body chatbox-popup__main"></div><div class="chatbox-popup__footer"><aside style="flex:10"><textarea type="text" placeholder="Scrivi qui il tuo messaggio..." rows="3" autofocus></textarea></aside><aside style="flex:1;color:#888;text-align:center;"><i class="fa fa-paper-plane ml-3" aria-hidden="true"></i></aside></div></div>',
                sanitize: false,
            })
        })
    </script>
</body>
</html>

fwa-button.js

class FloatingWhatsAppButton extends HTMLElement {
    #container;

    constructor() {
        super();

        var shadow = this.attachShadow( { mode: 'open' } );

        this.#container = document.createElement( 'div' );
        this.#container.setAttribute( 'slot', 'bootstrap' );

        var button = document.createElement( 'button' );
        button.setAttribute( 'type', 'button' );
        button.setAttribute( 'class', 'ccwhatsapp-starter' );
        button.setAttribute( 'data-toggle', 'popover' );

        var icon = document.createElement( 'i' );
        icon.setAttribute( 'class', 'fab fa-whatsapp fa-2x' );
        icon.setAttribute( 'aria-hidden', 'true' );

        button.appendChild( icon );
        this.#container.appendChild( button );

        var slot = document.createElement( 'slot' );
        slot.setAttribute( 'name', 'bootstrap' );
        var style = document.createElement( 'style' );
        style.textContent = '.ccwhatsapp-starter {' +
                                'position: fixed; ' +
                                'bottom: 16px;' +
                                'right: 16px;' +
                                'width: 58px; ' +
                                'height: 58px; ' +
                                'color: white; ' +
                                'background-color: green; ' +
                                'background-position: center center; ' +
                                'background-repeat: no-repeat; ' + 
                                'box-shadow: 12px 15px 20px 0 rgba(46, 61, 73, 0.2); ' +
                                'border: 0; ' +
                                'border-radius: 50%; ' +
                                'cursor: pointer;' +
                            '} ';

        shadow.appendChild( style );
        shadow.appendChild( slot );
    }

    connectedCallback() {
        this.appendChild( this.#container );
    }
}

// Define the new element
customElements.define( 'fwa-button', FloatingWhatsAppButton )

;


person icolumbro    schedule 20.03.2020    source источник


Ответы (1)


Если вы спрашиваете, как вы используете Bootstrap в своем компоненте, ответ будет просто повторить ссылку на стили и скрипты Bootstrap в теневой DOM вашего пользовательского элемента. Вызовы будут кэшироваться, поэтому дополнительная загрузка не будет, и ваша теневая DOM теперь будет иметь доступ к Bootstrap.

Если вы не хотите, чтобы родитель влиял на настраиваемый элемент, вам также придется изменить режим теневой DOM на закрытый var shadow = this.attachShadow( { mode: 'closed' } );

person moefinley    schedule 25.03.2020
comment
Спасибо, я попробую повторить ссылки, но у меня есть сомнения: скрипт Bootstrap работает в теневом DOM, несмотря на jQuery? - person icolumbro; 26.03.2020
comment
Если ему нужен jQuery, просто повторите ссылку JQuery. - person moefinley; 01.04.2020
comment
Отличный совет по добавлению ссылки Bootstrap к теневому элементу, работает как шарм! - person vulpxn; 28.08.2020