根据官方介绍,Unobtrusive scripting adapter for jQuery所做的就是

1.force confirmation dialogs for various actions;
2.make non-GET requests from hyperlinks;
3.make forms or hyperlinks submit data asynchronously with Ajax;
4.have submit buttons become automatically disabled on form submit to prevent double-clicking.

对于以下link_to helper

<%= link_to 'Destroy', article_path(article), method: :delete, data: { confirm: 'Are you sure?'  } %>


它所生成的<a>会被监听以下click事件



逐个点开来看,以下这个比较像样:监听整个document的click,并筛选出rails.linkClickSelector

$document.on('click.rails', rails.linkClickSelector, function(e) {
  var link = $(this), method = link.data('method'), data = link.data('params'), metaClick = e.metaKey || e.ctrlKey;
  if (!rails.allowAction(link)) return rails.stopEverything(e);

  if (!metaClick && link.is(rails.linkDisableSelector)) rails.disableElement(link);

  if (rails.isRemote(link)) {
    if (metaClick && (!method || method === 'GET') && !data) { return true; }

    var handleRemote = rails.handleRemote(link);
    // Response from rails.handleRemote() will either be false or a deferred object promise.
    if (handleRemote === false) {
      rails.enableElement(link);
    } else {
      handleRemote.fail( function() { rails.enableElement(link); } );
    }
    return false;

  } else if (method) {
    rails.handleMethod(link);
    return false;
  }
});


其中rails.linkClickSelecto如下,使handler只作用于a[data-xxx]标签(不包括a[data-disable-xxx])

$.rails = rails = {
  // Link elements bound by jquery-ujs
  linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote]:not([disabled]), a[data-disable-with], a[data-disable]',

  // Button elements bound by jquery-ujs
  buttonClickSelector: 'button[data-remote]:not([form]):not(form button), button[data-confirm]:not([form]):not(form button)',

  // Select elements bound by jquery-ujs
  inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]',

  // Form elements bound by jquery-ujs
  formSubmitSelector: 'form',

  // Form input elements bound by jquery-ujs
  formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])',

  // Form input elements disabled during form submission
  disableSelector: 'input[data-disable-with]:enabled, button[data-disable-with]:enabled, textarea[data-disable-with]:enabled, input[data-disable]:enabled, button[data-disable]:enabled, textarea[data-disable]:enabled',

  // Form input elements re-enabled after form submission
  enableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled, input[data-disable]:disabled, button[data-disable]:disabled, textarea[data-disable]:disabled',

  // Form required input elements
  requiredInputSelector: 'input[name][required]:not([disabled]), textarea[name][required]:not([disabled])',

  // Form file input elements
  fileInputSelector: 'input[name][type=file]:not([disabled])',

  // Link onClick disable selector with possible reenable after remote submission
  linkDisableSelector: 'a[data-disable-with], a[data-disable]',

  // Button onClick disable selector with possible reenable after remote submission
  buttonDisableSelector: 'button[data-remote][data-disable-with], button[data-remote][data-disable]',

  // ...
}


对于非remote(ajax)的,就使用rails.handleMethod(link)

handleMethod: function(link) {
  var href = rails.href(link),
    method = link.data('method'),
    target = link.attr('target'),
    csrfToken = rails.csrfToken(),
    csrfParam = rails.csrfParam(),
    form = $('
'),     metadataInput = '';   if (csrfParam !== undefined && csrfToken !== undefined && !rails.isCrossDomain(href)) {     metadataInput += '';   }   if (target) { form.attr('target', target); }   form.hide().append(metadataInput).appendTo('body');   form.submit(); }


它基本上做的就是从<a>中抽取data-xxx,拼接成一个form,然后submit

因此,对于一个如下的<a>

Destroy


步入该函数,会发现它抓得各种attribute和input如下



拼接出的<form>如下