jQuery ajax弹出浮动卡片

暂无标签

使用 powerFloat.js 有删减
仅保证ajax方式有效。

<script>$('[c]').powerFloat({targetMode: "ajax",});</script>
(function($) {
    $.fn.powerFloat = function(options) {
        return $(this).each(function() {
            var s = $.extend({}, defaults, options || {});
            var init = function(pms, trigger) {
                if (o.target && o.target.css("display") !== "none") {
                    o.targetClear();
                }
                o.s = pms;
                o.trigger = trigger;                
            };
            switch (s.eventType) {
                case "hover": {
                    $(this).hover(function() {
                        init(s, $(this));
                        var numShowDelay = parseInt(s.showDelay, 10), hoverTimer;    
                        //鼠标hover延时
                        if (numShowDelay) {
                            if (hoverTimer) {
                                clearTimeout(hoverTimer);
                            }
                            hoverTimer = setTimeout(function() {
                                o.targetGet();
                            }, numShowDelay);    
                        } else {
                            o.targetGet();    
                        }
                    }, function() {
                        o.flagDisplay = false;
                        o.targetHold();
                        if (s.hoverHold) {
                            setTimeout(function() {
                                o.displayDetect();    
                            }, 200);
                        } else {
                            o.displayDetect();
                        }
                    });
                    break;    
                }
                default: {
                    init(s, $(this));
                    o.targetGet();
                    $(document).unbind("mouseup");
                }
            }
        });
    };
    
    var o = {
        targetGet: function() {
            //一切显示的触发来源
            if (!this.trigger) { return this; }
            var attr = this.trigger.attr(this.s.targetAttr), target = this.s.target;
            switch (this.s.targetMode) {
                case "common": {
                    if (target) {
                        var type = typeof(target);
                        if (type === "object") {
                            if (target.size()) {
                                o.target = target.eq(0);
                            }
                        } else if (type === "string") {
                            if ($(target).size()) {
                                o.target = $(target).eq(0);
                            }    
                        }
                    } else {
                        if (attr && $("#" + attr).size()) {
                            o.target = $("#" + attr);
                        }
                    }
                    if (o.target) {
                        o.targetShow();
                    } else {
                        return this;    
                    }
                    
                    break;
                }
                case "ajax": {
                    //ajax元素,如图片,页面地址
                    var url = target || attr;
                    this.targetProtect = false;
                    
                    if (/(\.jpg|\.png|\.gif|\.bmp|\.jpeg)$/i.test(url)) {
                        if (o.cacheData[url]) {
                            o.target = $(o.cacheData[url]);
                            o.targetShow();
                        } else {
                            var tempImage = new Image();
                            o.loading();
                            tempImage.onload = function() {
                                var w = tempImage.width, h = tempImage.height;
                                var winw = $(window).width(), winh = $(window).height();
                                var imgScale = w / h, winScale = winw / winh;
                                if (imgScale > winScale) {
                                    //图片的宽高比大于显示屏幕
                                    if (w > winw / 2) {
                                        w = winw / 2;
                                        h = w / imgScale;    
                                    }
                                } else {
                                    //图片高度较高
                                    if (h > winh / 2) {
                                        h = winh / 2;
                                        w = h * imgScale;
                                    }
                                }
                                var imgHtml = '<img class="float_ajax_image" src="' + url + '" width="' + w + '" height = "' + h + '" />';
                                o.cacheData[url] = imgHtml;
                                o.target = $(imgHtml);
                                o.targetShow();
                            };
                            tempImage.onerror = function() {
                                o.target = $('<div class="float_ajax_error">图片加载失败。</div>');
                                o.targetShow();
                            };
                            tempImage.src = url;
                        }
                    } else {
                        if (url) {
                            if (o.cacheData[url]) {
                                o.target = $('<div class="float_ajax_data">' + o.cacheData[url] + '</div>');
                                o.targetShow();    
                            } else {
                                o.loading();
                                $.ajax({
                                    url: url,
                                    success: function(data) {
                                        if (typeof(data) === "string") {
                                            o.target = $('<div class="float_ajax_data">' + data + '</div>');
                                            o.targetShow();
                                            o.cacheData[url] = data;
                                        }
                                    },
                                    error: function() {
                                        o.target = $('<div class="float_ajax_error">数据没有加载成功。</div>');
                                        o.targetShow();
                                    }
                                });
                            }
                        }
                    }
                    break;
                }
            }
            return this;
        },
        container: function() {
            //容器(如果有)重装target
            var cont = this.s.container, mode = this.s.targetMode || "mode";
            if (mode === "ajax" || mode === "remind") {
                //显示三角
                this.s.sharpAngle = true;    
            } else {
                this.s.sharpAngle = false;
            }
            //是否反向
            if (this.s.reverseSharp) {
                this.s.sharpAngle = !this.s.sharpAngle;    
            }
            
            if (mode !== "common") {
                //common模式无新容器装载
                if (cont === null) {
                    cont = "plugin";    
                } 
                if ( cont === "plugin" ) {
                    if (!$("#floatBox_" + mode).size()) {
                        $('<div id="floatBox_' + mode + '" class="float_' + mode + '_box"></div>').appendTo($("body")).hide();
                    }
                    cont = $("#floatBox_" + mode);    
                } 
                
                if (cont && typeof(cont) !== "string" && cont.size()) {
                    if (this.targetProtect) {
                        o.target.show().css("position", "static");
                    }
                    o.target = cont.empty().append(o.target);
                }
            }
            return this;
        },
        setWidth: function() {
            var w = this.s.width;
            if (w === "auto") {
                if (this.target.get(0).style.width) {
                    this.target.css("width", "auto");    
                }
            } else if (w === "inherit") {
                this.target.width(this.trigger.width());
            } else {
                this.target.css("width", w);    
            }
            return this;
        },
        position: function() {
            var pos, tri_h = 0, tri_w = 0, cor_w = 0, cor_h = 0, tri_l, tri_t, tar_l, tar_t, cor_l, cor_t,
                tar_h = this.target.data("height"), tar_w = this.target.data("width"),
                st = $(window).scrollTop(),
                off_x = parseInt(this.s.offsets.x, 10) || 0, off_y = parseInt(this.s.offsets.y, 10) || 0,
                mousePos = this.cacheData;
            //缓存目标对象高度,宽度,提高鼠标跟随时显示性能,元素隐藏时缓存清除
            if (!tar_h) {
                tar_h = this.target.outerHeight();
                if (this.s.hoverFollow) {
                    this.target.data("height", tar_h);
                }
            }
            if (!tar_w) {
                tar_w = this.target.outerWidth();
                if (this.s.hoverFollow) {
                    this.target.data("width", tar_w);
                }
            }
            
            pos = this.trigger.offset();
            tri_h = this.trigger.outerHeight();
            tri_w = this.trigger.outerWidth();
            tri_l = pos.left;
            tri_t = pos.top;
            
            var funMouseL = function() {
                if (tri_l < 0) {
                    tri_l = 0;
                } else if (tri_l + tri_h > $(window).width()) {
                    tri_l = $(window).width() = tri_h;    
                }
            }, funMouseT = function() {
                if (tri_t < 0) {
                    tri_t = 0;
                } else if (tri_t + tri_h > $(document).height()) {
                    tri_t = $(document).height() - tri_h;
                }
            };
            var arrLegalPos = ["4-1", "1-4", "5-7", "2-3", "2-1", "6-8", "3-4", "4-3", "8-6", "1-2", "7-5", "3-2"],
                align = this.s.position, alignMatch = false, strDirect;
            $.each(arrLegalPos, function(i, n) {
                if (n === align) {
                    alignMatch = true;    
                    return;
                }
            });
            if (!alignMatch) {
                align = "4-1";
            }
            
            var funDirect = function(a) {
                var dir = "bottom";
                //确定方向
                switch (a) {
                    case "1-4": case "5-7": case "2-3": {
                        dir = "top";
                        break;
                    }
                    case "2-1": case "6-8": case "3-4": {
                        dir = "right";
                        break;
                    }
                    case "1-2": case "8-6": case "4-3": {
                        dir = "left";
                        break;
                    }
                    case "4-1": case "7-5": case "3-2": {
                        dir = "bottom";
                        break;
                    }
                }
                return dir;
            };
            
            //居中判断
            var funCenterJudge = function(a) {
                if (a === "5-7" || a === "6-8" || a === "8-6" || a === "7-5") {
                    return true;
                }
                return false;
            };
            
            var funJudge = function(dir) {
                var totalHeight = 0, totalWidth = 0, flagCorner = (o.s.sharpAngle && o.corner) ? true: false;
                if (dir === "right") {
                    totalWidth = tri_l + tri_w + tar_w + off_x;
                    if (flagCorner) {
                        totalWidth += o.corner.width();
                    }    
                    if (totalWidth > $(window).width()) {
                        return false;    
                    }
                } else if (dir === "bottom") {
                    totalHeight = tri_t + tri_h + tar_h + off_y;
                    if (flagCorner) {
                        totalHeight +=     o.corner.height();
                    }
                    if (totalHeight > st + $(window).height()) {
                        return false;    
                    }
                } else if (dir === "top") {
                    totalHeight = tar_h + off_y;
                    if (flagCorner) {
                        totalHeight +=     o.corner.height();
                    }
                    if (totalHeight > tri_t - st) {
                        return false;    
                    } 
                } else if (dir === "left") {
                    totalWidth = tar_w + off_x;
                    if (flagCorner) {
                        totalWidth += o.corner.width();
                    }
                    if (totalWidth > tri_l) {
                        return false;    
                    }
                }
                return true;
            };
            //此时的方向
            strDirect = funDirect(align);
            if (this.s.sharpAngle) {
                //创建尖角
                this.createSharp(strDirect);
            }
            
            //边缘过界判断
            if (this.s.edgeAdjust) {
                //根据位置是否溢出显示界面重新判定定位
                if (funJudge(strDirect)) {
                    //该方向不溢出
                    (function() {
                        if (funCenterJudge(align)) { return; }
                        var obj = {
                            top: {
                                right: "2-3",
                                left: "1-4"    
                            },
                            right: {
                                top: "2-1",
                                bottom: "3-4"
                            },
                            bottom: {
                                right: "3-2",
                                left: "4-1"    
                            },
                            left: {
                                top: "1-2",
                                bottom: "4-3"    
                            }
                        };
                        var o = obj[strDirect], name;
                        if (o) {
                            for (name in o) {
                                if (!funJudge(name)) {
                                    align = o[name];
                                }
                            }
                        }
                    })();
                } else {
                    //该方向溢出
                    (function() {
                        if (funCenterJudge(align)) { 
                            var center = {
                                "5-7": "7-5",
                                "7-5": "5-7",
                                "6-8": "8-6",
                                "8-6": "6-8"
                            };
                            align = center[align];
                        } else {
                            var obj = {
                                top: {
                                    left: "3-2",
                                    right: "4-1"    
                                },
                                right: {
                                    bottom: "1-2",
                                    top: "4-3"
                                },
                                bottom: {
                                    left: "2-3",
                                    right: "1-4"
                                },
                                left: {
                                    bottom: "2-1",
                                    top: "3-4"
                                }
                            };
                            var o = obj[strDirect], arr = [];
                            for (name in o) {
                                arr.push(name);
                            }
                            if (funJudge(arr[0]) || !funJudge(arr[1])) {
                                align = o[arr[0]];
                            } else {
                                align = o[arr[1]];    
                            }
                        }
                    })();
                }
            }
            
            //已确定的尖角
            var strNewDirect = funDirect(align), strFirst = align.split("-")[0];
            if (this.s.sharpAngle) {
                //创建尖角
                this.createSharp(strNewDirect);
                cor_w = this.corner.width(), cor_h = this.corner.height();
            }
            //确定left, top值
            switch (strNewDirect) {
                case "top": {
                    tar_t = tri_t - off_y - tar_h - cor_h;
                    if (strFirst == "1") {
                        tar_l = tri_l - off_x;    
                    } else if (strFirst === "5") {
                        tar_l = tri_l - (tar_w - tri_w) / 2 - off_x;
                    } else {
                        tar_l = tri_l - (tar_w - tri_w) - off_x;
                    }
                    cor_t = tri_t - cor_h - off_y - 1;
                    cor_l = tri_l - (cor_w - tri_w) / 2;
                    break;
                }
                case "right": {
                    tar_l = tri_l + tri_w + off_x + cor_w;
                    if (strFirst == "2") {
                        tar_t = tri_t + off_y;    
                    } else if (strFirst === "6") {
                        tar_t = tri_t - (tar_h - tri_h) / 2 + off_y;
                    } else {
                        tar_t = tri_t - (tar_h - tri_h) + off_y;
                    }
                    cor_l = tri_l + tri_w + off_x + 1;
                    cor_t = tri_t - (cor_h - tri_h) / 2;
                    break;
                }
                case "bottom": {
                    tar_t = tri_t + tri_h + off_y + cor_h;
                    if (strFirst == "4") {
                        tar_l = tri_l + off_x;    
                    } else if (strFirst === "7") {
                        tar_l = tri_l - (tar_w - tri_w) / 2 + off_x;
                    } else {
                        tar_l = tri_l - (tar_w - tri_w) + off_x;
                    }
                    cor_t = tri_t + tri_h + off_y + 1;
                    cor_l = tri_l - (cor_w - tri_w) / 2;
                    break;
                }
                case "left": {
                    tar_l = tri_l - tar_w - off_x - cor_w;
                    if (strFirst == "2") {
                        tar_t = tri_t - off_y;    
                    } else if (strFirst === "6") {
                        tar_t = tri_t - (tar_w - tri_w) / 2 - off_y;
                    } else {
                        tar_t = tri_t - (tar_h - tri_h) - off_y;
                    }
                    cor_l = tar_l + cor_w;
                    cor_t = tri_t - (tar_w - cor_w) / 2;
                    break;
                }
            }
            
            //尖角的显示
            if (cor_h && cor_w && this.corner) {
                this.corner.css({
                    left: cor_l,
                    top: cor_t,
                    zIndex: this.s.zIndex + 1    
                });
            }
            //浮动框显示
            this.target.css({
                position: "absolute",
                left: tar_l,
                top: tar_t,
                zIndex: this.s.zIndex
            });
            return this;
        },
        createSharp: function(dir) {
            var bgColor, bdColor, color1 = "", color2 = "";
            var objReverse = {
                left: "right",
                right: "left",
                bottom: "top",
                top: "bottom"    
            }, dirReverse = objReverse[dir] || "top";
            
            if (this.target) {
                bgColor = this.target.css("background-color");
                if (parseInt(this.target.css("border-" + dirReverse + "-width")) > 0) {
                    bdColor = this.target.css("border-" + dirReverse + "-color");
                } 
                
                if (bdColor &&  bdColor !== "transparent") {
                    color1 = 'style="color:' + bdColor + ';"';
                } else {
                    color1 = 'style="display:none;"';
                }
                if (bgColor && bgColor !== "transparent") {
                    color2 = 'style="color:' + bgColor + ';"';    
                }else {
                    color2 = 'style="display:none;"';
                }
            }
            
            var html = '<div id="floatCorner_' + dir + '" class="float_corner float_corner_' + dir + '">' +
                    '<span class="corner corner_1" ' + color1 + '>◆</span>' +
                    '<span class="corner corner_2" ' + color2 + '>◆</span>' +
                '</div>';
            if (!$("#floatCorner_" + dir).size()) {
                $("body").append($(html));    
            }
            this.corner = $("#floatCorner_" + dir);
            return this;
        },
        targetHold: function() {
            if (this.s.hoverHold) {
                var delay = parseInt(this.s.hideDelay, 10) || 200;
                this.target.hover(function() {
                    o.flagDisplay = true;
                }, function() {
                    o.flagDisplay = false;
                    //鼠标移出检测是否hover trigger,以决定其显示与否
                    setTimeout(function() {
                        o.displayDetect();    
                    }, delay);
                });
            }
            return this;
        },
        loading: function() {
            this.target = $('<div class="float_loading"><div class="loading"></div></div>');
            this.targetShow();
            this.target.removeData("width").removeData("height");
            return this;
        },
        displayDetect: function() {
            //显示与否检测与触发
            if (!this.flagDisplay) {
                this.targetHide();
            }
            return this;
        },
        targetShow: function() {
            o.cornerClear();
            this.flagDisplay = true;
            this.container().setWidth().position();
            this.target.show();
            if ($.isFunction(this.s.showCall)) {
                this.s.showCall.call(this.trigger, this.target);    
            }
            return this;
        },
        targetHide: function() {
            this.flagDisplay = false;
            this.targetClear();
            this.cornerClear();
            if ($.isFunction(this.s.hideCall)) {
                this.s.hideCall.call(this.trigger);    
            }
            this.target = null;
            this.trigger = null;
            this.s = {};
            this.targetProtect = false;
            return this;
        },
        targetClear: function() {
            if (this.target) {
                if (this.target.data("width")) {
                    this.target.removeData("width").removeData("height");    
                }
                if (this.targetProtect) {
                    //保护孩子
                    this.target.children().hide().appendTo($("body"));
                } 
                this.target.unbind().hide();
            }
        },
        cornerClear: function() {
            if (this.corner) {
                //使用remove避免潜在的尖角颜色冲突问题
                this.corner.remove();
            }
        },
        target: null,
        trigger: null,
        s: {},
        cacheData: {},
        targetProtect: false
    };
    
    $.powerFloat = {};
    $.powerFloat.hide = function() {
        o.targetHide();    
    };
    
    var defaults  = {
        width: "auto", //可选参数:inherit,数值(px)
        offsets: {
            x: 0,
            y: 0    
        },
        zIndex: 999,
        
        eventType: "hover", //事件类型,其他可选参数有:click, focus
        
        showDelay: 0, //鼠标hover显示延迟
        hideDelay: 0, //鼠标移出隐藏延时
        
        hoverHold: true,
        hoverFollow: false, //true或是关键字x, y
        
        targetMode: "common", //浮动层的类型,其他可选参数有:ajax, list, remind
        target: null, //target对象获取来源,优先获取,如果为null,则从targetAttr中获取。
        targetAttr: "href", //target对象获取来源,当targetMode为list时无效
        
        container: null, //转载target的容器,可以使用"plugin"关键字,则表示使用插件自带容器类型
        reverseSharp: false, //是否反向小三角的显示,默认ajax, remind是显示三角的,其他如list和自定义形式是不显示的
        
        position: "4-1", //trigger-target
        edgeAdjust: true, //边缘位置自动调整
        
        showCall: $.noop,
        hideCall: $.noop
    };
})(jQuery);

如此形式,html行内加c="1"识别href地址作为ajax加载内容来源。
如需修改,如改为rel地址作为ajax加载内容来源,改targetAttr为rel即可。