用 stopPropagation() 阻止事件冒泡

场景是,对一个元素(通常比较大,类似 navbar)已经设置好监听响应(比如点击事件),然后对其内部的元素有单独的事件,而此时不希望内部元素的点击事件触发父级元素的事件,就需要用到 stopPropagation() 方法。

比如:navbar 拥有点击事件 A,navbar 内部有个按钮拥有点击事件 B,默认点击按钮会同时触发事件 A 和 B,但往往不希望事件 A 被触发,点击按钮只是为了事件 B,所以需要关闭按钮的冒泡功能,防止按钮点击事件会扩展到父层的元素。

$("button").click(function(e){
  e.stopPropagation();
});

用 delegate 让事件注册到动态加入的元素

javascript 的普通事件注册有一个问题,就是只对页面加载时存在的元素生效,比如如下 click 事件,只对一开始就存在页面的 class-1 元素生效。而实际上很多时候我们会在使用过程中动态添加很多元素到页面,而动态添加的 class-1 是并不会拥有该 click 事件的。

$(".wrapper").find(".class-1").click(function(){
  $(this).toggleClass("test-class");
});

解决方法就是 delegate,它会给动态添加的元素也注册上声明的事件。不过,写法是必须要有个 wrapper 元素,如下所示:

$(".wrapper").delegate(".class-1", "click", function(){
  $(this).toggleClass("test-class");
});

select 级联

controller 返回一个 json,内容是二级 select 的 value 和显示内容

前端通过对一级 select 的 change 监听,发起 ajax 获取数据然后渲染二级 select

respond_to do |format|
  format.html
  format.json { render json: { result: collections.map{|c| [c.column_0, c.column_1]}, 
                               status: 200 
                             }
              }
end
$("#select_1").change(function(){    
  $.ajax({
      url: $(this).data('select'),
      dataType: "JSON",
      data: {'params_id': $(this).val()},
      type: "GET",
      success:function (data) {
        console.log(data);

        var options = '';
        data.result.forEach(function(item){
          var new_option = "<option value='" + item[0] + "'>" + item[1] + "</option>";
          options += new_option;
        })
        $("#select_2").html(options);

        // 当然,稍加改动就可以让 select 级联其它元素,比如改变 table
        // var table = '';
        // data.result.forEach(function(item){
        //   var row = "<tr><td>" + item[0] + "</td><td>" + item[1] + "</td></tr>";
        //   table += row;
        // });
        // $("tbody").html(table);
      },
      error:function(e) {
          // alert("系统异常,请稍候重试!");
      }
  });
});