我整理了一个 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 );