Ajax加载后,引导开关无法正常工作。

16

我正在使用ajax加载来获取页面上的一些内容。我正在使用bootstrap 3和bootstrap开关。当内容被加载时,bootstrap 3内容可以正常工作(您可以清楚地看到面板panel-primary)。但是,bootstrap开关内容不会被加载(您只能看到一些复选框)。有人知道如何使其正常工作吗?还是我应该寻找其他切换开关?如果是这样,那么哪些是可行的?

编辑:我尚未测试事件绑定,因为我无法让bootstrap开关css在ajax加载的代码上工作。事件绑定与css无关,对吗?

  1. 主HTML代码使用的脚本(带有ajax加载的代码)
  2. 主HTML代码
  3. 由主HTML代码加载到div中的代码

<!-- jQuery -->
<script src="../bower_components/jquery/dist/jquery.min.js"></script>

<!-- Bootstrap Core JavaScript -->
<script src="../bower_components/bootstrap/dist/js/bootstrap.min.js"></script>

 <!-- Bootstrap Toggle JavaScript -->
<script src="../bower_components/bootstrap-toggle-master/js/bootstrap-toggle.min.js"></script>

<!-- Metis Menu Plugin JavaScript -->
<script src="../bower_components/metisMenu/dist/metisMenu.js"></script>

<!-- Custom Theme JavaScript -->
<script src="../dist/js/sb-admin-2.js"></script>

<!-- Custom Domotica JavaScript -->
<script> $(document).ready(function(){
        // Set trigger and container variables
        var trigger = $('#side-menu li ul li a'),
        container = $('#page-wrapper');
        
        // Fire on click
        trigger.on('click', function(){
            
          // Set $this for re-use. Set target from data attribute
          var $this = $(this),
            target = $this.data('target');       
            alert("target: " + target)
          // Load target page into container
          container.load(target + '.html', function (response, status, xhr) {});
          // Stop normal link behavior
          return false;
        });
      });
</script>
<!DOCTYPE html>
<html lang="en">

<head>

  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Home automation web page">
  <meta name="author" content="">

  <title>Home</title>

  <!-- Bootstrap Core CSS -->
  <link href="../bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">

  <!-- Bootstrap toggle -->
  <link href="../bower_components/bootstrap-toggle-master/css/bootstrap-toggle.min.css" rel="stylesheet">

  <!-- MetisMenu CSS -->
  <link href="../bower_components/metisMenu/dist/metisMenu.min.css" rel="stylesheet">

  <!-- Custom CSS -->
  <link href="../dist/css/sb-admin-2.css" rel="stylesheet">

  <!-- Custom Fonts -->
  <link href="../bower_components/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">

  <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
  <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
  <!--[if lt IE 9]>
        <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
        <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
        <![endif]-->

</head>

<body>

  <div id="wrapper">

    <!-- Navigation -->
    <nav class="navbar navbar-default navbar-static-top" role="navigation" style="margin-bottom: 0">
      <div class="navbar-header">
        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
          <span class="sr-only">Toggle navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand" href="index.html">Home</a>
      </div>
      <!-- /.navbar-header -->

      <ul class="nav navbar-top-links navbar-right">


        <li class="dropdown">
          <a class="dropdown-toggle" data-toggle="dropdown" href="#">
            <i class="fa fa-bell fa-fw"></i>  <i class="fa fa-caret-down"></i>
          </a>
          <ul class="dropdown-menu dropdown-alerts">
            <li>
              <a href="#">
                <div>
                  <i class="fa fa-comment fa-fw"></i> Failure
                  <span class="pull-right text-muted small">No respons from Controller 1</span>
                </div>
              </a>
            </li>

          </ul>
          <!-- /.dropdown-alerts -->
        </li>
        <!-- /.dropdown -->
        <li class="dropdown">
          <a class="dropdown-toggle" data-toggle="dropdown" href="#">
            <i class="fa fa-gear fa-fw"></i>
          </a>
          <!-- /.dropdown-user -->
        </li>
        <!-- /.dropdown -->
        <li class="dropdown">
          <a class="dropdown-toggle" data-toggle="dropdown" href="#">
            <i class="fa fa-sign-out fa-fw"></i> 
          </a>
        </li>
        <!-- /.dropdown -->
      </ul>
      <!-- /.navbar-top-links -->

      <div class="navbar-default sidebar" role="navigation">
        <div class="sidebar-nav navbar-collapse">
          <ul class="nav" id="side-menu">
            <li>
              <a href="index"><i class="glyphicon glyphicon-home"></i> House<span class="fa arrow"></span></a>
              <ul class="nav nav-second-level">
                <li>
                  <a href="#">Weather</a>
                </li>
                <li>
                  <a href="#">Energy</a>
                </li>
                <li>
                  <a href="#">Water</a>
                </li>
              </ul>
            </li>
            <li>
              <a href="#"><i class="glyphicon glyphicon-star"></i> 1st floor<span class="fa arrow"></span></a>
              <ul class="nav nav-second-level" id="side-menu2">
                <li>
                  <a href="#" data-target="index">Hallway</a>
                </li>
                <li>
                  <a href="#">Main bedroom</a>
                </li>
              </ul>
              <!-- /.nav-second-level -->
            </li>
            <li>
              <a href="#"><i class="glyphicon glyphicon-star"></i> main floor<span class="fa arrow"></span></a>
              <ul class="nav nav-second-level">
                <li>
                  <a href="#">Kitchen</a>
                </li>
                <li>
                  <a href="#">Living room</a>
                </li>
                <li>
                  <a href="#">Garage</a>
                </li>
              </ul>
              <!-- /.nav-second-level -->
            </li>
            <li>
              <a href="#"><i class="glyphicon glyphicon-star"></i> Basement</a> 
              <!-- /.nav-second-level -->
            </li>
            <li>
              <a href="#"><i class="glyphicon glyphicon-tree-deciduous"></i> Garden</a> 
              <!-- /.nav-second-level -->
            </li>
          </ul>
        </div>
        <!-- /.sidebar-collapse -->
      </div>
      <!-- /.navbar-static-side -->
    </nav>

    <div id="page-wrapper">

    </div>
    <!-- /#page-wrapper -->

  </div>
  <!-- /#wrapper -->
</body>

</html>

    <div class="panel panel-primary" id="switchespanel">
          <div class="panel-heading">
            <h3 class="panel-title">Switches</h3>
        </div>
        <div class="panel-body">
            <table class="table">
                <tr>
                    <th>Location</th>
                    <th>State</th>
                </tr>
                <tr>                
                <td>Testswitch0</td>
                    <td>
                        <label>
                            <input type="checkbox" data-toggle="toggle" data-onstyle="success" id="S0" data-size="mini">
                        </label>
                    </td>                 
                </tr>   
            </table>
        </div>
    </div>

1
尝试使用 $(document).on('click', '#side-menu li ul li a', function(){ });。请注意,document 应该是层次结构中更接近目标元素的另一个元素。 - Wesley Smith
1
CSS甚至没有加载到复选框上,这不仅仅是事件绑定的问题,我尝试了你提出的解决方案,但没有成功。 - Michvw
你使用的是哪个版本的Bootstrap? - Wesley Smith
顺便提一句,你的 HTML 不合法,你不能像你现在这样用 <div id="checkbox"></div> 包裹 td 元素,你需要一个嵌套的表格而不是一个 div,并且你也多次使用了 id="checkbox",这是无效的。只是提醒一下。 - Wesley Smith
显示剩余2条评论
2个回答

16

请确保你正确加载了bootstrap-toggle的js和css文件。具体来说,检查它们是否位于你链接指向的位置,或者使用下面列出的cdn版本:

<link href="https://gitcdn.github.io/bootstrap-toggle/2.2.0/css/bootstrap-toggle.min.css" rel="stylesheet">
<script src="https://gitcdn.github.io/bootstrap-toggle/2.2.0/js/bootstrap-toggle.min.js"></script>

你的路径可能有误或者你直接忘记引入js文件了,否则代码应该是没有问题的,你应该在控制台上看到一个关于此的警告信息。

关于动态加载内容

第一个元素能正常工作是因为在html首次加载之后,bootstrap-toggle.min.js会查找所有带有属性data-toggle="toggle"的元素,并对它们调用.bootstrapToggle()应用插件。这仅发生在页面加载时。

如果你随后添加更多的开关,你需要通过.bootstrapToggle()自行初始化它们。我已经更新下面的示例来模拟动态添加开关并解释我将采取的方法。有关更多详细信息,请参见代码中的注释。

      // timeout to simulate ajax
setTimeout(function(){ 
   // add an element dynamically,
  $('.table').append('<tr><td>Testswitch0</td><td><label><input type="checkbox" data-toggle="toggle" data-onstyle="success" id="S2" data-size="mini"></label></td></tr>');
    
    // now that we have dynamically loaded elements
    // we need to initialize any toggles that were added
    // you shouldn't re-initialize any toggles already present
    // but we also do want to have to figure out how to find the ones we added
    // instead, we'll destroy all toggles and recreate all new ones
    $("[data-toggle='toggle']").bootstrapToggle('destroy')                 
    $("[data-toggle='toggle']").bootstrapToggle();
  
}, 2000)
      
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link href="https://gitcdn.github.io/bootstrap-toggle/2.2.0/css/bootstrap-toggle.min.css" rel="stylesheet">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="https://gitcdn.github.io/bootstrap-toggle/2.2.0/js/bootstrap-toggle.min.js"></script>
<div class="panel panel-primary" id="switchespanel">
  <div class="panel-heading">
    <h3 class="panel-title">Switches</h3>
  </div>
  <div class="panel-body">
    <table class="table">
      <tr>
        <th>Location</th>
        <th>State</th>
      </tr>
      <tr>
        <td>Testswitch0</td>
        <td><label>
            <input type="checkbox" data-toggle="toggle" data-onstyle="success" id="S0" data-size="mini">
          </label></td>
      </tr>
      <tr>
        <td>Testswitch0</td>
        <td><label>
            <input type="checkbox" data-toggle="toggle" data-onstyle="success" id="S1" data-size="mini">
          </label></td>
      </tr>
    </table>
  </div>
</div>


谢谢,使用您的代码确实完美地呈现了Bootstrap开关的CSS。它确实会干扰我的HTML页面的其余部分,但通过删除Bootstrap链接和脚本(也许是因为它们这样加载两次?)可以解决这个问题。无论在删除Bootstrap链接和脚本之前还是之后,开关都无法切换,但这可能是一个事件绑定问题,不是吗? - Michvw
您的主题使用了一个 CSS 文件,覆盖了默认的 Bootstrap CSS。为此,他们在 Bootstrap CSS 文件之后加载了一个 CSS 文件。如果您在该文件之后重新添加 Bootstrap CSS,则会抵消更改,这就是为什么这样做会影响您的主题。您不需要再次包含 Bootstrap。从我的示例中(除了正确的 URL 之外),最重要的是文件加载的顺序,请确保无论从何处获取文件,加载顺序都相同。 - Wesley Smith
谢谢你的教训!你有没有想法为什么在ajax加载后切换不起作用? - Michvw
@Michvw 没问题,查看我的更新以获取动态内容信息。 - Wesley Smith

3
最好的解决方案是:
1- 在加载bootstrap之前先加载Jquery。让Jquery排在最前面,然后是Ajax,最后是bootstrap。
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle@3.6.1/js/bootstrap4-toggle.min.js"></script>

2- 在ajax完成后调用bootstrapToggle:

    $(document).ajaxComplete(function() {
        $('input[type=checkbox][data-toggle^=toggle]').bootstrapToggle();
    });

3- 注意:在结尾处调用您的自定义脚本jquery


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接