jquery plug in unobtrusive implements fragmented loading

  • 2020-06-15 07:38:56
  • OfStack

Without further ado, I will first share the source code with you.


//ajax Support library 
/*!
** Unobtrusive Ajax support library for jQuery
** Copyright (C) Microsoft Corporation. All rights reserved.
*/

/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */
/*global window: false, jQuery: false */
/*
data-ajax=true // Open the binding 
data-ajax-mode// Form of renewal  BEFORE Insert before the object  AFTER Insert after the object   Null means overwrite 
data-ajax-update// Updated object 
data-ajax-confirm// Set up the 1 If not, do not set 
data-ajax-loading// According to loading The object of 
data-ajax-loading-duration// The duration of the   The default is 0
data-ajax-method// submission 
data-ajax-url// submit url
data-ajax-begin//ajax The function or 1 Section of the program 
data-ajax-complete// After the completion of the ( function ) , the returned data has not yet been loaded and is called on either successful or failed requests 
data-ajax-success// successful ( function ) , loading completed data 
data-ajax-failure// Failure, error

*/

(function ($) {
  var data_click = "unobtrusiveAjaxClick",
    data_validation = "unobtrusiveValidation";
  // The first 2 Core, determine if the function is not, then construct 1 Anonymous function 
  function getFunction(code, argNames) {
    var fn = window, parts = (code || "").split(".");
    while (fn && parts.length) {
      fn = fn[parts.shift()];
    }// The lookup function name is sometimes a namespace for example xxx.xxx
    if (typeof (fn) === "function") {
      return fn;
    }
    argNames.push(code);
    // If it is not a function object, it constructs it 1 One and back, hang! 
    return Function.constructor.apply(null, argNames);
  }

  function isMethodProxySafe(method) {
    return method === "GET" || method === "POST";
  }
  // Various submission methods can be added, which should be Web Api Do add 
  function asyncOnBeforeSend(xhr, method) {
    if (!isMethodProxySafe(method)) {
      xhr.setRequestHeader("X-HTTP-Method-Override", method);
    }
    // Note: X-HTTP-Method-Override is 1 Nonstandard HTTP The header. 
    // This is for unable to send certain HTTP Request type (for example PUT or DELETE ) and designed by the client 
  }
  // After the completion of the 
  function asyncOnSuccess(element, data, contentType) {
    var mode;

    if (contentType.indexOf("application/x-javascript") !== -1) { // jQuery already executes JavaScript for us
      return;
    }

    mode = (element.getAttribute("data-ajax-mode") || "").toUpperCase();
    $(element.getAttribute("data-ajax-update")).each(function (i, update) {
      var top;

      switch (mode) {
      case "BEFORE":
        top = update.firstChild;
        $("<div />").html(data).contents().each(function () {
          update.insertBefore(this, top);
        });
        break;
      case "AFTER":
        $("<div />").html(data).contents().each(function () {
          update.appendChild(this);
        });
        break;
      default:
        $(update).html(data);
        break;
      }
    });
  }
  // The main function 
  // Binding objects and parameters 
  function asyncRequest(element, options) {
    var confirm, loading, method, duration;

    confirm = element.getAttribute("data-ajax-confirm");
    if (confirm && !window.confirm(confirm)) {
      return;
    }

    loading = $(element.getAttribute("data-ajax-loading"));//
    duration = element.getAttribute("data-ajax-loading-duration") || 0;// The default is 0

    $.extend(options, {
      type: element.getAttribute("data-ajax-method") || undefined,
      url: element.getAttribute("data-ajax-url") || undefined,
      beforeSend: function (xhr) {//ajax Trigger before, here xhr Will be used below apply Passing out 
        var result;
        asyncOnBeforeSend(xhr, method);// Determine whether to add a special submission method 
        result = getFunction(element.getAttribute("data-ajax-begin"), ["xhr"]).apply(this, arguments);//argument : Replaces one of the function objects 1 A property object that stores parameters. This is passing in the original parameters. Hang! 
        if (result !== false) {
          loading.show(duration);
        }
        return result;
      },
      complete: function () {
        loading.hide(duration);
        getFunction(element.getAttribute("data-ajax-complete"), ["xhr", "status"]).apply(this, arguments);
      },
      success: function (data, status, xhr) {
        asyncOnSuccess(element, data, xhr.getResponseHeader("Content-Type") || "text/html");
        getFunction(element.getAttribute("data-ajax-success"), ["data", "status", "xhr"]).apply(this, arguments);
      },
      error: getFunction(element.getAttribute("data-ajax-failure"), ["xhr", "status", "error"])
    });

    options.data.push({ name: "X-Requested-With", value: "XMLHttpRequest" });

    method = options.type.toUpperCase();// A capital 
    if (!isMethodProxySafe(method)) {
      options.type = "POST";
      options.data.push({ name: "X-HTTP-Method-Override", value: method });
    }
    // It's all going to be called jquery the ajax
    $.ajax(options);
  }

  function validate(form) {
    // You can cancel validation 
    var validationInfo = $(form).data(data_validation);
    return !validationInfo || !validationInfo.validate || validationInfo.validate();
  }


  
  $(document).on("click", "a[data-ajax=true]", function (evt) {
    evt.preventDefault();
    asyncRequest(this, {
      url: this.href,
      type: "GET",
      data: []
    });
  });

  $(document).on("click", "form[data-ajax=true] input[type=image]", function (evt) {// This is not used very often 
    var name = evt.target.name,
      $target = $(evt.target),
      form = $target.parents("form")[0],
      offset = $target.offset();

    $(form).data(data_click, [
      { name: name + ".x", value: Math.round(evt.pageX - offset.left) },
      { name: name + ".y", value: Math.round(evt.pageY - offset.top) }
    ]);

    setTimeout(function () {
      $(form).removeData(data_click);
    }, 0);
  });

  $(document).on("click", "form[data-ajax=true] :submit", function (evt) {
    var name = evt.target.name,
      form = $(evt.target).parents("form")[0];

    $(form).data(data_click, name ? [{ name: name, value: evt.target.value }] : []);

    setTimeout(function () {
      $(form).removeData(data_click);
    }, 0);
  });

  $(document).on("submit", "form[data-ajax=true]", function (evt) {
    var clickInfo = $(this).data(data_click) || [];
    evt.preventDefault();
    if (!validate(this)) {
      return;
    }
    asyncRequest(this, {
      url: this.action,
      type: this.method || "GET",
      data: clickInfo.concat($(this).serializeArray())// Well written, serialized form and spliced, later ajax Either way, it's convenient 
    });
  });
  // extension 
  function bindDataAjax(obj) {
    $(obj).on("click", "a[data-ajax=true]", function (evt) {
      evt.preventDefault();
      asyncRequest(this, {
        url: this.href,
        type: "GET",
        data: []
      });
    });

    $(obj).on("click", "form[data-ajax=true] input[type=image]", function (evt) {// This is not used very often 
      var name = evt.target.name,
        $target = $(evt.target),
        form = $target.parents("form")[0],
        offset = $target.offset();

      $(form).data(data_click, [
        { name: name + ".x", value: Math.round(evt.pageX - offset.left) },
        { name: name + ".y", value: Math.round(evt.pageY - offset.top) }
      ]);

      setTimeout(function () {
        $(form).removeData(data_click);
      }, 0);
    });

    $(obj).on("click", "form[data-ajax=true] :submit", function (evt) {
      var name = evt.target.name,
        form = $(evt.target).parents("form")[0];

      $(form).data(data_click, name ? [{ name: name, value: evt.target.value }] : []);

      setTimeout(function () {
        $(form).removeData(data_click);
      }, 0);
    });

    $(obj).on("submit", "form[data-ajax=true]", function (evt) {
      var clickInfo = $(this).data(data_click) || [];
      evt.preventDefault();
      if (!validate(this)) {
        return;
      }
      asyncRequest(this, {
        url: this.action,
        type: this.method || "GET",
        data: clickInfo.concat($(this).serializeArray())// Well written, serialized form and spliced, later ajax Either way, it's convenient 
      });
    });
  }
  $.fn.unobtrusive = function (option, param) {
    if (typeof options == "string") {
      return $.fn.unobtrusive.methods[options](this, param);
    }
    
  }
  // methods 
  $.fn.unobtrusive.methods = {
    resetbind: function (jq) {// The corresponding object is reinitialized 
      return jq.each(function () {
        //bindDataAjax($(this), obj);
        //bindDataAjax(obj);
        bindDataAjax(jq);
      });
    }
  }
}(jQuery));


Where the word // extension appears, I write the extension without interfering with the original code (it is my principle and respect to others not to modify others' code as much as possible). The function provides code bindings for the specified area, using methods


$(obj).unobtrusive('resetbind')

DOM object binding where the binding is required. For example, fragment loading of 1 page


<a href="javascript:;" data-ajax-mode="" data-ajax-update=".down-content" data-ajax="true" data-ajax-method="get" data-ajax-url="/Admin/UserAdd" data-ajax-loading="#load"  data-ajax-success="$('.down-content').unobtrusive('resetbind')"> add </a>

Load the code after Ajax into the.down-ES18en container and render and bind them (as does easyui in UI)

I mentioned in the fragment loading method that load of jquery can also be implemented under 1. The open source MvcAdmin in my previous blog used load, but it is still the html method of jquery. load internal is the Ajax encapsulation, then use html loaded into the page up, source of load http like this: / / www css88. com/tool/jQuerySourceViewer / # v = 1.7.2 & fn=jQuery.fn.load

Special remind

data-ajax-begin //ajax triggered before the function or 1 segment of the program

data-ajax-complete // After completion, the returned data has not yet been loaded and is called on either successful or failed requests

data-ajax-success // Successfully loaded data completed

The function to which these three arguments are called must be a string, without the need for (). For example, data-ES63en-ES64en =" function name ", not ES65en-ES66en-ES67en =" function name ()", no parenthesis required!

This is the end of this article, I hope you enjoy it.


Related articles: