【问题标题】:Where to initialize jquery for laravel在哪里为 laravel 初始化 jquery
【发布时间】:2021-06-25 03:19:16
【问题描述】:

我正在尝试将拖放功能添加到我的精美树中。但是,我在哪里初始化 jquery 库似乎存在问题,导致错误消息表明我尝试使用的 jquery 函数不可用等。

具体错误信息 = app.js:24 jQuery.Deferred 异常:$(...).perfectScrollbar is not a function TypeError: $(...).perfectScrollbar is not a function

如果我直接初始化一个完美的滚动条,它会继续反映其他库不是函数等

代码的简单概述(经过编辑以显示主刀片已经需要 jquery 一次)

--大师之刃--

    <!DOCTYPE html>
    <html lang="{{ config('app.locale') }}" @if (config('voyager.multilingual.rtl')) dir="rtl" @endif>
    <head>
        <title>@yield('page_title', setting('admin.title') . " - " . setting('admin.description'))</title>

    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="csrf-token" content="{{ csrf_token() }}"/>
    <!-- Google Fonts -->
    <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,700" rel="stylesheet">

    <!-- Favicon -->
    <link rel="shortcut icon" href="{{ voyager_asset('images/logo-icon.png') }}" type="image/x-icon">

    <!-- App CSS -->
    <link rel="stylesheet" href="{{ voyager_asset('css/app.css') }}">

    <!-- fancy tree jquery/css-->
    @yield('css')


    @if(config('voyager.multilingual.rtl'))
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-rtl/3.4.0/css/bootstrap-rtl.css">
        <link rel="stylesheet" href="{{ voyager_asset('css/rtl.css') }}">
    @endif

    <!-- Few Dynamic Styles -->
    <style type="text/css">
        .voyager .side-menu .navbar-header {
            background:#FFFFFF;
            border-color:#FFFFFF;
            {{--background:{{ config('voyager.primary_color','#22A7F0') }};--}}
            {{--border-color:{{ config('voyager.primary_color','#22A7F0') }};--}}
        }
        .widget .btn-primary{
            border-color:{{ config('voyager.primary_color','#22A7F0') }};
        }
        .widget .btn-primary:focus, .widget .btn-primary:hover, .widget .btn-primary:active, .widget .btn-primary.active, .widget .btn-primary:active:focus{
            background:{{ config('voyager.primary_color','#22A7F0') }};
        }
        .voyager .breadcrumb a{
            color:{{ config('voyager.primary_color','#22A7F0') }};
        }
        .app-container .side-menu .panel.widget h5 {
            float: left;
            display: block;
            position: absolute;
            top: 0px;
            width: 180px;
            text-align: left;
            opacity: 0;
            transition: opacity .3s ease;
            margin-top: 17px;
            left: 68px;
            overflow: hidden;
            height: 29px;
        }
        .app-container .side-menu .panel.widget h6 {
            float: left;
            display: block;
            position: absolute;
            top: 15px;
            width: 180px;
            text-align: left;
            opacity: 0;
            transition: opacity .3s ease;
            margin-top: 17px;
            left: 68px;
            overflow: hidden;
            height: 29px;
        }
        .app-container.expanded .panel.widget h5 {
            opacity: 1;
        }
        .app-container.expanded .panel.widget h6 {
            opacity: 1;
        }
        .app-container .side-menu:hover .panel.widget h5 {
            opacity: 1;
        }
        .app-container .side-menu:hover .panel.widget h6 {
            opacity: 1;
        }
    </style>

    @if(!empty(config('voyager.additional_css')))<!-- Additional CSS -->
        @foreach(config('voyager.additional_css') as $css)<link rel="stylesheet" type="text/css" href="{{ asset($css) }}">@endforeach
    @endif

    @yield('head')
</head>

<body class="voyager @if(isset($dataType) && isset($dataType->slug)){{ $dataType->slug }}@endif">

<div id="voyager-loader">
    <?php $admin_loader_img = Voyager::setting('admin.loader', ''); ?>
    @if($admin_loader_img == '')
        <img src="{{ voyager_asset('images/logo-icon.png') }}" alt="Voyager Loader">
    @else
        <img src="{{ Voyager::image($admin_loader_img) }}" alt="Voyager Loader">
    @endif
</div>

<?php
if (starts_with(Auth::user()->avatar, 'http://') || starts_with(Auth::user()->avatar, 'https://')) {
    $user_avatar = Auth::user()->avatar;
} else {
    $user_avatar = Voyager::image(Auth::user()->avatar);
}
?>

<div class="app-container">
    <div class="fadetoblack visible-xs"></div>
    <div class="row content-container">
        @include('voyager::dashboard.navbar')
        @include('voyager::dashboard.sidebar')
        <script>
            (function(){
                    var appContainer = document.querySelector('.app-container'),
                        sidebar = appContainer.querySelector('.side-menu'),
                        navbar = appContainer.querySelector('nav.navbar.navbar-top'),
                        loader = document.getElementById('voyager-loader'),
                        hamburgerMenu = document.querySelector('.hamburger'),
                        sidebarTransition = sidebar.style.transition,
                        navbarTransition = navbar.style.transition,
                        containerTransition = appContainer.style.transition;

                    sidebar.style.WebkitTransition = sidebar.style.MozTransition = sidebar.style.transition =
                    appContainer.style.WebkitTransition = appContainer.style.MozTransition = appContainer.style.transition =
                    navbar.style.WebkitTransition = navbar.style.MozTransition = navbar.style.transition = 'none';

                    if (window.localStorage && window.localStorage['voyager.stickySidebar'] == 'true') {
                        appContainer.className += ' expanded no-animation';
                        loader.style.left = (sidebar.clientWidth/2)+'px';
                        hamburgerMenu.className += ' is-active no-animation';
                    }

                   navbar.style.WebkitTransition = navbar.style.MozTransition = navbar.style.transition = navbarTransition;
                   sidebar.style.WebkitTransition = sidebar.style.MozTransition = sidebar.style.transition = sidebarTransition;
                   appContainer.style.WebkitTransition = appContainer.style.MozTransition = appContainer.style.transition = containerTransition;
            })();
        </script>
        <!-- Main Content -->
        <div class="container-fluid">
            <div class="side-body padding-top">
                @yield('page_header')
                <div id="voyager-notifications"></div>
                @yield('content')
            </div>
        </div>
    </div>
</div>
@include('voyager::partials.app-footer')

<!-- Javascript Libs -->
<script type="text/javascript" src="{{ voyager_asset('js/app.js') }}"></script>

<!-- <script type="text/javascript" src="{{ voyager_asset('js/app.js') }}"></script> -->


<script>
    @if(Session::has('alerts'))
        let alerts = {!! json_encode(Session::get('alerts')) !!};
        helpers.displayAlerts(alerts, toastr);
    @endif

    @if(Session::has('message'))

    // TODO: change Controllers to use AlertsMessages trait... then remove this
    var alertType = {!! json_encode(Session::get('alert-type', 'info')) !!};
    var alertMessage = {!! json_encode(Session::get('message')) !!};
    var alerter = toastr[alertType];

    if (alerter) {
        alerter(alertMessage);
    } else {
        toastr.error("toastr alert-type " + alertType + " is unknown");
    }

    @endif
</script>

@yield('javascript')
<!-- Javascript Libs -->
<!-- <script type="text/javascript" src="{{ voyager_asset('js/app.js') }}"></script> -->


@if(!empty(config('voyager.additional_js')))<!-- Additional Javascript -->
    @foreach(config('voyager.additional_js') as $js)<script type="text/javascript" src="{{ asset($js) }}"></script>@endforeach
@endif

</body>
</html>

--花式树刃--

Extends Master Blade
@section('content')
--fancy tree code--
@stop
@section('javascript)
<script src="//code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="//code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<script src="/src/jquery-ui-dependencies/jquery.fancytree.ui-deps.js" type="text/javascript"></script>
<script src="/src/jquery.fancytree.js" type="text/javascript"></script>
<script src="/src/jquery.fancytree.dnd.js" type="text/javascript"></script>
<script src="/src/jquery.fancytree.edit.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
        // using default options
        $("#tree").fancytree({
            extensions: ["dnd"],
            checkbox: false,
            icon: false,
            generateIds: true,
            dnd: {
                autoExpandMS: 400,
                focusOnClick: true,
                preventVoidMoves: true, // Prevent dropping nodes 'before self', etc.
                preventRecursiveMoves: true, // Prevent dropping nodes on own descendants
                dragStart: function(node, data) {
                /** This function MUST be defined to enable dragging for the tree.
                 *  Return false to cancel dragging of node.
                 */
                return true;
                },
                dragEnter: function(node, data) {
                /** data.otherNode may be null for non-fancytree droppables.
                 *  Return false to disallow dropping on node. In this case
                 *  dragOver and dragLeave are not called.
                 *  Return 'over', 'before, or 'after' to force a hitMode.
                 *  Return ['before', 'after'] to restrict available hitModes.
                 *  Any other return value will calc the hitMode from the cursor position.
                 */
                // Prevent dropping a parent below another parent (only sort
                // nodes under the same parent)
        /*           if(node.parent !== data.otherNode.parent){
                    return false;
                }
                // Don't allow dropping *over* a node (would create a child)
                return ["before", "after"];
        */
                return true;
                },
                dragDrop: function(node, data) {
                /** This function MUST be defined to enable dropping of items on
                 *  the tree.
                 */
                data.otherNode.moveTo(node, data.hitMode);
                }
            },
}

【问题讨论】:

  • 我的猜测是页面上方有更多未显示的脚本标签......并且正在加载 jQuery.js 两次
  • 是的,在花哨的树文件中的 javascript 部分生成之前,我确实有另一个需要 jquery 的 javascript 标记。你会建议我如何解决这个问题?
  • 将这个&lt;!-- Javascript Libs --&gt; &lt;script type="text/javascript" src="{{ voyager_asset('js/app.js') }}"&gt;&lt;/script&gt; 放在主刀片中的&lt;/body&gt; &lt;/html&gt; 之前并尝试
  • 它返回一个错误,其中 jquery.js:3850 Uncaught TypeError: $(...).fancytree is not a function。
  • 我已经把js文件放在了底部,还有@stopFancy Tree Blade中的javascript部分试试这个

标签: html jquery laravel laravel-blade fancytree


【解决方案1】:

大多数时候都会出现这个错误

TypeError: $(…).perfectScrollbar 不是函数

是因为脚本顺序错误,有时是因为启用了 jQuery 的版本。在master.blade中,页面在调用@include('voyager::partials.app-footer')之后立即带来@yield('javascript'),并确保@include('voyager::partials.app-footer')中没有任何js文件,如果它会再次导致同样的错误,所以取出js文件并导入它在你的 master.blade 文件中。

试试这个

我正在尝试将拖放功能添加到我的精美树中。但是,我在哪里初始化 jquery 库似乎存在问题,导致错误消息表明我尝试使用的 jquery 函数不可用等。

具体错误信息 = app.js:24 jQuery.Deferred 异常:$(...).perfectScrollbar is not a function TypeError: $(...).perfectScrollbar is not a function

如果我直接初始化一个完美的滚动条,它会继续反映其他库不是函数等

代码的简单概述(编辑以显示主刀片已经需要一次 jquery)

--大师之刃--

    <!DOCTYPE html>
    <html lang="{{ config('app.locale') }}" @if (config('voyager.multilingual.rtl')) dir="rtl" @endif>
    <head>
        <title>@yield('page_title', setting('admin.title') . " - " . setting('admin.description'))</title>

    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="csrf-token" content="{{ csrf_token() }}"/>
    <!-- Google Fonts -->
    <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,700" rel="stylesheet">

    <!-- Favicon -->
    <link rel="shortcut icon" href="{{ voyager_asset('images/logo-icon.png') }}" type="image/x-icon">

    <!-- App CSS -->
    <link rel="stylesheet" href="{{ voyager_asset('css/app.css') }}">

    <!-- fancy tree jquery/css-->
    @yield('css')


    @if(config('voyager.multilingual.rtl'))
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-rtl/3.4.0/css/bootstrap-rtl.css">
        <link rel="stylesheet" href="{{ voyager_asset('css/rtl.css') }}">
    @endif

    <!-- Few Dynamic Styles -->
    <style type="text/css">
        .voyager .side-menu .navbar-header {
            background:#FFFFFF;
            border-color:#FFFFFF;
            {{--background:{{ config('voyager.primary_color','#22A7F0') }};--}}
            {{--border-color:{{ config('voyager.primary_color','#22A7F0') }};--}}
        }
        .widget .btn-primary{
            border-color:{{ config('voyager.primary_color','#22A7F0') }};
        }
        .widget .btn-primary:focus, .widget .btn-primary:hover, .widget .btn-primary:active, .widget .btn-primary.active, .widget .btn-primary:active:focus{
            background:{{ config('voyager.primary_color','#22A7F0') }};
        }
        .voyager .breadcrumb a{
            color:{{ config('voyager.primary_color','#22A7F0') }};
        }
        .app-container .side-menu .panel.widget h5 {
            float: left;
            display: block;
            position: absolute;
            top: 0px;
            width: 180px;
            text-align: left;
            opacity: 0;
            transition: opacity .3s ease;
            margin-top: 17px;
            left: 68px;
            overflow: hidden;
            height: 29px;
        }
        .app-container .side-menu .panel.widget h6 {
            float: left;
            display: block;
            position: absolute;
            top: 15px;
            width: 180px;
            text-align: left;
            opacity: 0;
            transition: opacity .3s ease;
            margin-top: 17px;
            left: 68px;
            overflow: hidden;
            height: 29px;
        }
        .app-container.expanded .panel.widget h5 {
            opacity: 1;
        }
        .app-container.expanded .panel.widget h6 {
            opacity: 1;
        }
        .app-container .side-menu:hover .panel.widget h5 {
            opacity: 1;
        }
        .app-container .side-menu:hover .panel.widget h6 {
            opacity: 1;
        }
    </style>

    @if(!empty(config('voyager.additional_css')))<!-- Additional CSS -->
        @foreach(config('voyager.additional_css') as $css)<link rel="stylesheet" type="text/css" href="{{ asset($css) }}">@endforeach
    @endif

    @yield('head')
</head>

<body class="voyager @if(isset($dataType) && isset($dataType->slug)){{ $dataType->slug }}@endif">

<div id="voyager-loader">
    <?php $admin_loader_img = Voyager::setting('admin.loader', ''); ?>
    @if($admin_loader_img == '')
        <img src="{{ voyager_asset('images/logo-icon.png') }}" alt="Voyager Loader">
    @else
        <img src="{{ Voyager::image($admin_loader_img) }}" alt="Voyager Loader">
    @endif
</div>

<?php
if (starts_with(Auth::user()->avatar, 'http://') || starts_with(Auth::user()->avatar, 'https://')) {
    $user_avatar = Auth::user()->avatar;
} else {
    $user_avatar = Voyager::image(Auth::user()->avatar);
}
?>

<div class="app-container">
    <div class="fadetoblack visible-xs"></div>
    <div class="row content-container">
        @include('voyager::dashboard.navbar')
        @include('voyager::dashboard.sidebar')
        <script>
            (function(){
                    var appContainer = document.querySelector('.app-container'),
                        sidebar = appContainer.querySelector('.side-menu'),
                        navbar = appContainer.querySelector('nav.navbar.navbar-top'),
                        loader = document.getElementById('voyager-loader'),
                        hamburgerMenu = document.querySelector('.hamburger'),
                        sidebarTransition = sidebar.style.transition,
                        navbarTransition = navbar.style.transition,
                        containerTransition = appContainer.style.transition;

                    sidebar.style.WebkitTransition = sidebar.style.MozTransition = sidebar.style.transition =
                    appContainer.style.WebkitTransition = appContainer.style.MozTransition = appContainer.style.transition =
                    navbar.style.WebkitTransition = navbar.style.MozTransition = navbar.style.transition = 'none';

                    if (window.localStorage && window.localStorage['voyager.stickySidebar'] == 'true') {
                        appContainer.className += ' expanded no-animation';
                        loader.style.left = (sidebar.clientWidth/2)+'px';
                        hamburgerMenu.className += ' is-active no-animation';
                    }

                   navbar.style.WebkitTransition = navbar.style.MozTransition = navbar.style.transition = navbarTransition;
                   sidebar.style.WebkitTransition = sidebar.style.MozTransition = sidebar.style.transition = sidebarTransition;
                   appContainer.style.WebkitTransition = appContainer.style.MozTransition = appContainer.style.transition = containerTransition;
            })();
        </script>
        <!-- Main Content -->
        <div class="container-fluid">
            <div class="side-body padding-top">
                @yield('page_header')
                <div id="voyager-notifications"></div>
                @yield('content')
            </div>
        </div>
    </div>
</div>
@include('voyager::partials.app-footer')

@yield('javascript')

<!-- Javascript Libs -->
<script type="text/javascript" src="{{ voyager_asset('js/app.js') }}"></script>

<!-- <script type="text/javascript" src="{{ voyager_asset('js/app.js') }}"></script> -->


<script>
    @if(Session::has('alerts'))
        let alerts = {!! json_encode(Session::get('alerts')) !!};
        helpers.displayAlerts(alerts, toastr);
    @endif

    @if(Session::has('message'))

    // TODO: change Controllers to use AlertsMessages trait... then remove this
    var alertType = {!! json_encode(Session::get('alert-type', 'info')) !!};
    var alertMessage = {!! json_encode(Session::get('message')) !!};
    var alerter = toastr[alertType];

    if (alerter) {
        alerter(alertMessage);
    } else {
        toastr.error("toastr alert-type " + alertType + " is unknown");
    }

    @endif
</script>


<!-- Javascript Libs -->
<!-- <script type="text/javascript" src="{{ voyager_asset('js/app.js') }}"></script> -->


@if(!empty(config('voyager.additional_js')))<!-- Additional Javascript -->
    @foreach(config('voyager.additional_js') as $js)<script type="text/javascript" src="{{ asset($js) }}"></script>@endforeach
@endif

</body>
</html>

--花式树刃--

Extends Master Blade
@section('content')
--fancy tree code--
@stop
@section('javascript)
<script type="text/javascript">
$(function(){
        // using default options
        $("#tree").fancytree({
            extensions: ["dnd"],
            checkbox: false,
            icon: false,
            generateIds: true,
            dnd: {
                autoExpandMS: 400,
                focusOnClick: true,
                preventVoidMoves: true, // Prevent dropping nodes 'before self', etc.
                preventRecursiveMoves: true, // Prevent dropping nodes on own descendants
                dragStart: function(node, data) {
                /** This function MUST be defined to enable dragging for the tree.
                 *  Return false to cancel dragging of node.
                 */
                return true;
                },
                dragEnter: function(node, data) {
                /** data.otherNode may be null for non-fancytree droppables.
                 *  Return false to disallow dropping on node. In this case
                 *  dragOver and dragLeave are not called.
                 *  Return 'over', 'before, or 'after' to force a hitMode.
                 *  Return ['before', 'after'] to restrict available hitModes.
                 *  Any other return value will calc the hitMode from the cursor position.
                 */
                // Prevent dropping a parent below another parent (only sort
                // nodes under the same parent)
        /*           if(node.parent !== data.otherNode.parent){
                    return false;
                }
                // Don't allow dropping *over* a node (would create a child)
                return ["before", "after"];
        */
                return true;
                },
                dragDrop: function(node, data) {
                /** This function MUST be defined to enable dropping of items on
                 *  the tree.
                 */
                data.otherNode.moveTo(node, data.hitMode);
                }
            },
}

<script src="//code.jquery.com/jquery-3.4.1.min.js"></script>
    <script src="//code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
    <script src="/src/jquery-ui-dependencies/jquery.fancytree.ui-deps.js" type="text/javascript"></script>
    <script src="/src/jquery.fancytree.js" type="text/javascript"></script>
    <script src="/src/jquery.fancytree.dnd.js" type="text/javascript"></script>
    <script src="/src/jquery.fancytree.edit.js" type="text/javascript"></script>

【讨论】:

  • 我尝试将 jquery 脚本更改为您建议的内容,但是我仍然遇到相同的错误,即完美的滚动条不是功能。老实说,我不知道我错过了什么/做错了什么。我尝试将花哨的树 DND 演示中的代码复制粘贴到一个单独的 php 项目中,该项目运行良好,但它只是在我需要它的这个 laravel 项目上运行时出现问题。 @Basharmal
  • 告诉我主刀片你有什么有时如果app.js文件在上面它会显示同样的错误app.js文件应该在底部
  • @include('voyager::partials.app-footer') 在生成花哨的树内容之前,我在主体标签内的主文件中确实有这组代码
  • 所以这就是你收到错误的原因,所以在看中它会解决问题之后获取 js/app.js 文件
  • 这样做会导致 .fancytree 未被识别为函数的错误。
猜你喜欢
  • 2014-04-27
  • 2015-06-27
  • 1970-01-01
  • 1970-01-01
  • 2023-02-04
  • 2015-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多