在jQuery插件中访问原始目标元素

时间:2013-03-18 14:33:02

标签: javascript jquery

我整理了一个jQuery插件来查询服务器并显示工具提示弹出窗口。是的,我知道可能有更好的可用,但我的一半动机是自己学习如何做到这一点。现场演示位于http://jsfiddle.net/sVZah/,脚本如下所示。将鼠标悬停在元素上时,我希望允许开发人员添加要发送到服务器的其他数据。我的想法是将getData()方法添加到我的插件中(请注意,jsfiddle示例不会这样做,因为它需要传递demoJSON对象来模拟ajax)。问题是方法中的this是指工具提示而不是初始元素(即p.myElement)因此我无法访问与原始元素相关联的数据(即data-id)。我应该如何访问getData方法中的原始目标元素?如果我的整体方法不理想,请让我知道并推荐一个更好的方法,因为这是一个非常学习的经历。

作为一个非官方的问题,如何防止悬停在元素的右侧启动弹出窗口?我认识到这可能更像是一个HTML问题,虽然我不希望得到答案,但我很乐意得到答案。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
        <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" /> 
        <title>screenshot</title>  
        <script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script> 
        <script src="jquery.ajaxTip.js" type="text/javascript"></script> 
        <style type="text/css">

            .myElement{margin:100px;}
            .ajaxToolActive{color:blue;}

            .myAjaxTip {
                position:absolute;
                border:1px solid #CECECE;
                background:white;
                padding:10px;
                display:none;
                color:black;
                font-size:11px;-moz-border-radius:4px;
                box-shadow: 3px 1px 6px #505050;
                -khtml-border-radius:4px;
                -webkit-border-radius:4px;
                border-radius:4px;
            }
        </style> 

        <script type="text/javascript">
            $(function(){
                $('.myElement').ajaxTip({
                    display: function(d){return '<p>'+d.name+'</p><p>'+d.address+'</p><p>'+d.city+', '+d.state+'</p>';},
                    getData:function(){console.log(this);return {id:123}},
                    'class':'myAjaxTip'
                });
            });
        </script>
    </head>

    <body>
        <p class="myElement" data-id="1" title="ajaxTip Popup">John Doe</p>
        <p class="myElement" data-id="2" title="ajaxTip Popup">Jane Doe</p>
        <p class="myElement" data-id="3" title="ajaxTip Popup">Baby Doe</p>
    </body> 
</html> 


/*
* jQuery ajaxTip
* Copyright 2013 Michael Reed
* Dual licensed under the MIT and GPL licenses.
* 
* Notes
*/
(function( $ ){

    var methods = {
        init : function( options ) {
            // Create some defaults, extending them with any options that were provided
            var settings = $.extend({
                'url'      : 'getAjaxTip.php',        //To include extra data sent to the server, included it in the url
                'class'    : 'standardAjaxTip',
                'mouseMove': true,
                'delay'    : 250,   //miliseconds to delay before requesting data from server
                'xOffset'  : 20,
                'yOffset'  : 10,
                'dataType' : 'json',
                'getData'  : function(){return {}}, //Use to set additional data to the server
                'display'  : function(data){   //User function must include function(data) {... return string}
                    var string='';
                    for (var key in data) {string+='<p>'+data[key]+'</p>';}
                    return string;
                }
                }, options  || {});     //Just in case user doesn't provide options

            return this.each(function(){
                var showing,title,timeoutID,ajax,$t=$(this),ajaxTip;
                $t.hover(function(e) {
                    if(!showing){
                        title = this.title;this.title = "";//Prevent title from being displayed,and save for later to put back    
                        timeoutID=window.setTimeout(function() {
                            ajax=$.get( settings.url,settings.getData(),function(data){
                                ajaxTip=$('<div />').addClass(settings.class).html(((title != '')?'<h3>'+title+'</h3>':'')+settings.display(data))
                                .css("top",(e.pageY - settings.yOffset) + "px")
                                .css("left",(e.pageX + settings.xOffset) + "px")
                                .appendTo('body').fadeIn("fast");                    
                                showing = true;
                                $t.addClass('ajaxToolActive');
                                }, settings.dataType);
                            },settings.delay); //Delay before requesting data from server
                    }
                    },
                    function()
                    {
                        //When not hover
                        if (typeof ajax == 'object') {ajax.abort();}
                        window.clearTimeout(timeoutID);
                        this.title = title;    
                        $t.removeClass('ajaxToolActive');
                        if(showing){ajaxTip.remove();}
                        showing = false;
                });

                $t.mousemove(function(e) {
                    if(settings.mouseMove && showing) {ajaxTip.css("top",(e.pageY - settings.yOffset) + "px").css("left",(e.pageX + settings.xOffset) + "px");}
                });
            });
        },

        //Add additional methods as needed
        //destroy : function() {}

    };

    $.fn.ajaxTip = function(method) {
        if ( methods[method] ) {
            return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
        } else if ( typeof method === 'object' || ! method ) {
            return methods.init.apply( this, arguments );
        } else {
            $.error( 'Method ' +  method + ' does not exist on jQuery.ajaxTip' );
        }    
    };


})( jQuery );

1 个答案:

答案 0 :(得分:1)

您可以使用apply或call方法更改getData的上下文

ajax=$.get( settings.url, settings.getData.call($t),function(data){

在这种情况下,在getData函数中,这将是$t jquery对象,因此您可以调用

$('.myElement').ajaxTip({

    display: function(d){
        return '<p>'+d.name+'</p><p>'+d.address+'</p><p>'+d.city+', '+d.state+'</p>';
    },
    getData:function(){
       alert(this.data('id'));
    },
    'class':'myAjaxTip'
});