分享一下自用的jQuery扩展文件

自己平日使用的jQuery的扩展文件.集成了一些常用的功能,我会不定时的更新这些文件.目前实现的功能如下:

  1. pull_down 页面拉到底部的事件函数,可以用来页面拉到底部的触发动作
  2. pop_alert 替换alert 需要font-awesome 字体图标的支持
  3. close_alert 关闭alert
  4. upload 上传图片
/*我的jquery的扩展函数*/


var __is_bottom_prev_obj = null; // 辅助判断滑动方向的对象
var is_bottom = function (jq_obj, y_val, y_threshold, callback, args) {
    /*
     * params jq_obj:      绑定滑动事件的元素的jQuery的对象.
     * params y_val:       滑动事件中去取出来的触摸点的y坐标event.touches[0].clientY
     * params callback:    回调函数, post和对dom的操作可以写在回调函数里
     * params args:        回调函数的参数组成的列表
     */
    try {
        y_threshold = parseInt(y_threshold);
        y_threshold = isNaN(y_threshold) ? 100 : y_threshold;
    } catch (e) {
        console.log(e);
        y_threshold = 100; // 在到达底部后,再滑动多少距离就激活事件? 单位像素
    }
    callback = callback == undefined ? function (s) {
        s = s == undefined ? '' : s;
        alert(s);
    } : callback;
    args = args == undefined ? ["hello world"] : args;
    // 判断是否到达底部?
    var win_height = $(window).height(); // 页面窗口高度
    var rect = jq_obj[0].getBoundingClientRect(); // 元素的宽高顶左的位置对象
    var dom_top = rect.top; // 元素顶部
    var dom_height = rect.height; // 元素高度.
    if ((win_height - (dom_top + dom_height)) < 1) {

        console.log("到达底部");
        // 如果y_val的值在持续减小.而dom_top不变的话,那就是滑到页面的底部了.
        if (__is_bottom_prev_obj == null) {
            // 第一次有效的滑动到底部
            __is_bottom_prev_obj = {
                "y": y_val,
                "date": new Date()
            };
        } else {
            // 判断是否超时?滑动距离是否足够?
            var old_y = __is_bottom_prev_obj['y'];
            var old_date = __is_bottom_prev_obj['date'];
            var now = new Date();
            var delta = now - old_date; // 时间差, 毫秒
            console.log("滑动间隔" + delta + "毫秒")
            if (delta <= 200) {
                // 连续的下滑动作,没有超时,检测滑动距离
                var l = (old_y - y_val);
                console.log("滑动距离" + l + "px")
                if (l >= y_threshold) {
                    // 滑动距离足够
                    __is_bottom_prev_obj = null; // 重置辅助判断的对象.
                    callback.apply(null, args); // 激活回调函数
                } else {
                    // pass
                }
            } else {
                // 滑动间隔超时
                __is_bottom_prev_obj = null; // 重置辅助判断的对象.
            }
        }
    } else {
        // 页面不在底部
        if (__is_bottom_prev_obj == null) {
            // pass
        } else {
            __is_bottom_prev_obj = null; // 重置辅助判断的对象.
        }
    }
}

var touch_it = function (selector, cb, args) {
    /*
    cb 回调函数
    args 回调函数的参数数组
    在touchmove事件中:
    1. 根据触摸点的y坐标的变化,判断是在往上还是往下滑动屏幕.
    */
    var $obj = $(selector);
    $obj.on("touchstart touchmove", function (event) {
        console.log(event);
        var e_name = event.type; // 时间类型
        var y = undefined;      // 触摸点y坐标
        try {
            y = event.originalEvent.touches[0].clientY; // touchend事件的touches属性是一个空的列表
        } catch (e) {
            console.warn("error!");
            console.log(`type: ${e_name}`);
            console.log(event.touches);
        }
        var dom_top = $obj.offset().top;

        is_bottom($obj, y, null, cb, args);
        var rect_top = $obj[0].getBoundingClientRect();
        var e = $(`
type:${e_name}, y=${parseInt(y)}, h1=${dom_top}, h2=${rect_top.top}
`); $(".tips").prepend(e); }); }; var pop_alert = function(title, delay){ // 弹出提示框 title = title==undefined?"读取中,请稍后...":title; var id_str = "8c8431579bbd44e6ad4758ddb3afccfd"; var $obj = $("#" + id_str); if($obj.size() == 0){ var html = `
${title}
`; $("body").append(html); } else{ $obj.find(".8c8431579bbd44").text(title).show(); } delay = delay==undefined?30000: delay; setTimeout(function(){ // 最多30秒关闭窗口 $("#" + id_str).hide(); }, delay); }; var close_alert = function(){ var id_str = "8c8431579bbd44e6ad4758ddb3afccfd"; var $obj = $("#" + id_str); $obj.hide(); }; var ajax_error = function(req, status, error, req_args, u){ /* ajax请求错误回调 error = NOT FOUND 404 error = FORBIDDEN 403 error = FORBIDDEN 401 error = INTERNAL SERVER ERROR 500 ... 每次ajax出错的时候,会记录下出错的信息.发送到日志接口. 如果发送到日志接口出错.那就保存在本地的会话里,不再由本函数发送. (将由其他的函数进行批量处理,暂时不实现 2018-9-13) */ console.log("Ajax_Error start"); // console.log(req); // console.log(status); console.log(u); console.log(error); console.log(req_args); console.log("Ajax_Error end"); var now = new Date(); var error_time = `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()} ${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}.${now.getMilliseconds()}` console.log(`error time is ${error_time}`); // 这是其他函数post失败的情况 var args = { "args": JSON.stringify(req_args), "url": u, "ajax_error_count": 1, "error": error, "error_time": error_time } $.post("/teacher/log", args, function(r){ close_alert(); alert("操作失败"); try{ var a = JSON.parse(r); console.log(a); } catch(e){ console.log(r); } }); }; var post_plus = function (url, args, callback){ var setting = { url: url, type: "POST", error:function(arg1, arg2, arg3){ajax_error(arg1, arg2,arg3, args, url)}, // 请求完成时的回调. data: args, // 参数 success: callback // 成功时的回调 }; $.ajax(setting); }; function upload_progress(event, progress_cb){ /* 上传进度处理函数 :params event: 文件上传事的事件, :params progress_cb: 回调函数,本函数会把上传完成的百分数当作地一个参数传入此回调函数. 默认情况下.会在控制台打印上传完成度. 注意,100并不代表服务端完整的接收到了文件. 只代表页面已经发送完了所有的文件内容. */ if (event.lengthComputable) { var complete_percent = Math.round(event.loaded * 100 / event.total); var handler = progress_cb?progress_cb: function(num){console.log(`上传完成度:${num}`)}; handler(complete_percent); }else{} } function upload_complete(event, success_cb){ /* 上传文件success时的事件,只要服务器返回状态码200,就会执行本函数,并并不是代表服务器返回了正确的信息. 根据实际需要可以覆盖. :params event: 文件上传事的事件,一般由XMLHttpRequest的upload的事件监听器来传递事件. :params success_cb: 成功时的回调函数, :return: nothing */ let str = event.target.responseText; let handler = success_cb? success_cb: function(a){console.log(a);}; handler(str); } function upload_error(event, error_cb){ /* 上传文件失败时的事件,根据实际需要可以覆盖. :params event: 文件上传事的事件,一般由XMLHttpRequest的upload的事件监听器来传递事件. :params error_cb: 失败时的回调函数, :return: nothing */ let handler = error_cb? error_cb: function(a){console.log(event);}; handler(event); } function upload_abort(event, abort_cb){ /* 上传文件被中止时的事件,根据实际需要可以覆盖. :params event: 文件上传事的事件,一般由XMLHttpRequest的upload的事件监听器来传递事件. :params abort_cb: 被终止时的回调函数, :return: nothing */ let handler = abort_cb? abort_cb: function(a){console.log(event);}; handler(event); } function my_upload(options){ /* 上传文件.用于绑定$的方法 options = { file_name: 字符串, file_data: DOM.files[0]对象, url: str, max_size: 整数, headers: 键值对对象, success_cb: function, error_cb: function, progress_cb: function, } :params file_name: 文件名. :params file_data: 文件数据,二进制对象 :params url: 上传的服务器url :params max_size: 上传文件的最大尺寸,单位kb :params headers: 放入header的参数,是键值对形式的字典,键名不要用下划线,因为那不符合规范 :params success_cb: 成功时的回调函数,会把服务器的返回信息作为第一个参数传入此回调函数. :params error_cb: 失败时的回调函数,会把错误信息作为第一个参数传入此回调函数. :params progress_cb: 上传时的返回上传进度的回调函数,会把页面上传文件的百分书作为第一个参数传入此回调函数.. :return: 不返回数据,由回调函数返回. 有关XMLHttpRequest对象的详细信息,请参考. https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest 有关XMLHttpRequest.send方法的详细文档地址: https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/send */ let file_name = options['file_name']; let file_data = options['file_data']; let url = options['url']; let max_size = options['max_size']; let headers = options['headers']; let success_cb = options['success_cb']; let error_cb = options['error_cb']; let progress_cb = options['progress_cb']; let prog_func = function(event){upload_progress(event, progress_cb)}; // 进度的回调函数 let comp_func = function(event){upload_complete(event, success_cb)}; // 成功时的回调函数 let erro_func = function(event){upload_error(event, error_cb)}; // 失败时的回调函数 let file_size = 0; try{ file_size = file_data.size; }catch(e){ console.log(e); } if(file_size === 0){ let ms = "无效的文件尺寸"; erro_func(ms); } else{ let can_exe = false; if(max_size === undefined){ can_exe = true; } else{ file_size = file_size / 1000; if(file_size > max_size){ let ms = `文件尺寸过大: 限制:${max_size}, 当前大小:${file_size} kb`; erro_func(ms); can_exe = false; } else{ can_exe = true; } } if(can_exe){ // 构造数据容器 let data = new FormData(); data.append(file_name, file_data); // 新建一个请求对象 let req = new XMLHttpRequest(); // 添加事件监听器 req.upload.addEventListener("progress", prog_func, false); req.addEventListener("load", comp_func, false); req.addEventListener("error", erro_func, false); req.addEventListener("abort", erro_func, false); req.open("post", url); // 必须在open之后才能给请求头赋值 if(headers){ /* * 传送请求头信息,目前服务端还未做对应的处理.这只是与被给后来使用的. * */ for(let k in headers){ req.setRequestHeader(k, headers[k]); } } try{ req.send(data); // 404错误会直接在此抛出 }catch(e){ let handler = error_cb? error_cb: function(ms){console.log(ms);}; handler(e); } } else{ // nothing... } return can_exe; } } function my_upload2($obj, url, success_cb, error_cb){ /* 上传文件2. 用于绑定dom的方法,想对于my_upload函数,本函数功能上进行了精简,如需精细控制,请使用my_upload函数 :params $obj: dom的jQuery对象 :params url: 上传的服务器url :params success_cb: 成功时的回调函数,会把服务器的返回信息作为第一个参数传入此回调函数. :params error_cb: 失败时的回调函数,会把错误信息作为第一个参数传入此回调函数. :return: 不返回数据,由回调函数返回. options = { file_name: 字符串, file_data: DOM.files[0]对象, url: str, max_size: 整数, headers: 键值对对象, success_cb: function, error_cb: function, progress_cb: function, } */ let file_name = $obj.attr("name"); if(file_name){ // nothing... } else{ file_name = "file" } let file_data = $obj[0].files[0]; let opts = { file_name: file_name, file_data: file_data, max_size: 2000, url: url, success_cb: success_cb, error_cb: error_cb, }; return my_upload(opts); } /*扩展函数注册区域*/ $.extend({ upload: my_upload, // 上传文件 post: post_plus, //重定义post pop_alert: function(arg){pop_alert(arg);}, // 弹出事件 close_alert: function(){close_alert();} // 强制关闭弹出事件 }); $.fn.extend({ upload: function(url, cb1, cb2){my_upload2($(this), url, cb1, cb2);}, // 上传文件. pull_down: function (call_back, args) { /*call_back 回调函数, args回调函数的参数的数组*/ touch_it($(this), call_back, args); // 页面下滑到底部后,继续下拉发生的事件 } });

你可能感兴趣的:(分享一下自用的jQuery扩展文件)