2013-03-16 97 views
0

我创建了一个jQuery插件,它通过ajax查询服务器并显示一个弹出窗口。然后我想要另一个页面返回一些不同的数据并显示它。我实现它的方式是,插件会发送数据,指出它到达服务器的页面,服务器会获取数据并发回数据类型,客户端会根据给定类型的数据显示它。扩展抽象jQuery插件

我的方法显然有很多不足之处。相反,是否可以创建插件的抽象版本,然后将其扩展到每个特定的应用程序,以便正确显示它(即摆脱switch语句)?另外,如何避免在弹出窗口上使用一个id(即#screenshot),这样每个窗口都可以单独设置样式?谢谢

ayb={}; 
$("a.screenshot").screenshotPreview(); 

function contact(data) 
{ 
    return '<dl><dt>Name:</dt><dd>'+data.firstname+' '+data.lastname+'</dd>' 
    +'<dt>Account:</dt><dd>'+data.account_name+'</dd>' 
    +'<dt>Name:</dt><dd>'+data.firstname+' '+data.lastname+'</dd>' 
    +((data.title)?'<dt>Title:</dt><dd>'+data.title+'</dd>':'') 
    +'<dt>User Name:</dt><dd>'+data.username+'</dd>' 
    +'<dt>Password:</dt><dd>'+data.password+'</dd>' 
    +'<dt>Communication Method:</dt><dd>'+data.communication_method+'</dd>' 
    +((data.email)?'<dt>Email:</dt><dd>'+data.email+'</dd>':'') 
    +((data.account_phone)?'<dt>Account Phone:</dt><dd>'+display_phone(data.account_phone)+'</dd>':'') 
    +((data.phone)?'<dt>Direct Phone:</dt><dd>'+display_phone(data.phone)+'</dd>':'') 
    +((data.mobile_phone)?'<dt>Mobile Phone:</dt><dd>'+display_phone(data.mobile_phone)+'</dd>':'') 
    +((data.account_fax)?'<dt>Account Fax:</dt><dd>'+display_phone(data.account_fax)+'</dd>':'') 
    +((data.fax)?'<dt>Direct Fax:</dt><dd>'+display_phone(data.fax)+'</dd>':'') 
    +((data.address || data.location)?'<dt>Address:</dt><dd>'+data.address+((data.address && data.location)?'<br>':'')+data.location+'</dd>':'') 
    +((data.email)?'<dt>Email:</dt><dd>'+data.email+'</dd>':'') 
    +'</dl>'; 
} 
function account(data) 
{ 
    return '<dl><dt>Name:</dt><dd>'+data.name+'</dd>' 
    +((data.phone)?'<dt>Account Phone:</dt><dd>'+display_phone(data.phone)+'</dd>':'') 
    +((data.fax)?'<dt>Account Fax:</dt><dd>'+display_phone(data.fax)+'</dd>':'') 
    +((data.address || data.location)?'<dt>Address:</dt><dd>'+data.address+((data.address && data.location)?'<br>':'')+data.location+'</dd>':'') 
    +((data.vertical_markets)?'<dt>Primary Market:</dt><dd>'+data.vertical_markets+'</dd>':'') 
    +((data.priority)?'<dt>Priority:</dt><dd>'+data.priority+'</dd>':'') 
    +'</dl>'; 
} 
function user(data) 
{ 
    return '<dl><dt>Name:</dt><dd>'+data.firstname+' '+data.lastname+'</dd>' 
    +'<dt>User Name:</dt><dd>'+data.username+'</dd>' 
    +((data.phone)?'<dt>Direct Phone:</dt><dd>'+display_phone(data.phone)+'</dd>':'') 
    +((data.mobile_phone)?'<dt>Mobile Phone:</dt><dd>'+display_phone(data.mobile_phone)+'</dd>':'') 
    +((data.fax)?'<dt>Direct Fax:</dt><dd>'+display_phone(data.fax)+'</dd>':'') 
    +((data.email)?'<dt>Email:</dt><dd>'+data.email+'</dd>':'') 
    +'</dl>'; 
} 
function getUrlVars(href) 
{ 
    //Returns object based on variables in url. Used to send data to GET 
    var vars = {}, hash, hashes = href.slice(href.indexOf('?') + 1).split('&'); 
    for(var i = 0; i < hashes.length; i++) 
    { 
     hash = hashes[i].split('='); 
     vars[hash[0]] = hash[1]; 
    } 
    return vars; 
} 


(function($){ 
    $.fn.screenshotPreview = function() { 
     //Apply to links to get a preview of the link 

     //Config - Set popup's distance from the cursor 
     ayb.screenshot={}; 
     ayb.screenshot.xOffset = 20; 
     ayb.screenshot.yOffset = 10; 
     ayb.screenshot.showing=false; 

     this.hover(function(e) 
     { 
      if(!ayb.screenshot.showing){ 
       ayb.screenshot.title = this.title;this.title = "";//Prevent title from being displayed,and save for later to put back  
       var url=getUrlVars(this.href); 
       ayb.screenshot.timeoutID=window.setTimeout(function() { 
        ayb.screenshot.showing = true; 
        url.task="getPopup"; //specify task 
        ayb.screenshot.ajax=$.ajax({ 
         url: 'index.php', 
         data: url, 
         success: function(data) 
         { 
          //Determine how to display returned data 
          switch (data.type) 
          { 
           case 'contact':var string=contact(data);break; 
           case 'account':var string=account(data);break; 
           case 'user':var string=user(data);break; 
           case 'project':var string=project(data);break; 
           default:var string='Error'; 
          } 
          $("body").append('<div id="screenshot">'+((ayb.screenshot.title != '')?'<h3>'+ayb.screenshot.title+'</h3>':null)+string+"</div>");         
          $("#screenshot") 
          .css("top",(e.pageY - ayb.screenshot.yOffset) + "px") 
          .css("left",(e.pageX + ayb.screenshot.xOffset) + "px") 
          .fadeIn("fast");      
         }, 
        dataType: 'json' 
        }); 
       },250); //Wait 1/4 of a second before requesting data from server 
      } 
     }, 
     function() 
     { 
      //When not hover 
      if (typeof ayb.screenshot.ajax == 'object') {ayb.screenshot.ajax.abort();} 
      window.clearTimeout(ayb.screenshot.timeoutID); 
      this.title = ayb.screenshot.title;  
      $("#screenshot").remove(); 
      ayb.screenshot.showing = false; 
     });  
     this.mousemove(function(e) 
     { 
      $("#screenshot").css("top",(e.pageY - ayb.screenshot.yOffset) + "px").css("left",(e.pageX + ayb.screenshot.xOffset) + "px"); 
     }); 
    }; 
})(jQuery); 
+0

如果你更详细地描述了你想要抽象的部分以及你想如何使用它们,将会有所帮助。可以在javascript选项对象中定义插件的各种选项,或者在标记中使用'data-'属性。至于风格,为什么不能为每种类型的主要内容添加不同的类?不清楚样式问题是什么...细节将有助于 – charlietfl 2013-03-16 18:45:51

+0

@charlietfl。我想分开的部分主要是我如何接收数据,然后使用客户端使用类似'string = contact(data)'来呈现数据;'根据您的评论,听起来我可以(也应该)定义某种选项,它甚至可以是处理显示数据的回调函数。 – user1032531 2013-03-16 18:57:40

回答

1

几个想法可能会有所帮助。首先是在标记使用data-属性:

<a href="#" class="screenshot" data-type="user">User Link</a> 

下一步是创造一个更通用的模板方法。使用类型可以从HTML data-type,并通过添加类相同的类型(或键入相关一些其它协议)的应采取你可以有不同的用例不同的CSS

DEMO JS:

(function ($) { 

    var shotTemplate = function (data, type) { 
     this.shot = { 
      start: '<div id="screenshot" class="' + type + '">', 
      end: '</div>},' 
     }; 
     this.user = function() { 
      /* not suggesting "data.type" protocol, was just simple for my demo*/ 
      return '<div class="user_class">' + data.user + '</div>'; 
     }; 
     this.contact = function() { 
      return '<div class="contact_class">' + data.contact + '</div>'; 
     }; 
     this.account= function() { 
      return '<div class="account_class">' + data.account + '</div>'; 
     }; 

     return this.shot.start + this[type]() + this.shot.end; 

    }; 



    $.fn.screenshotPreview = function() { 
     return this.each(function() { 
      var $el = $(this); 
      /* isolate screenshot to this instance*/ 
      var $screenshot; 
      $el.hover(function() { 
       $.post(url,data,function(response){ 
         $screenshot = $(shotTemplate(response, $el.data('type'))); 
         $('body').append($screenshot); 
       }); 
      }, function() { 
       $screenshot.remove(); 
      }) 

     }); 

    }; 
})(jQuery); 

CSS:

#screenshot.user{background:navy;color:white} 
#screenshot.contact{background:#444;color:white} 

DEMO:http://jsfiddle.net/wceDc/

我不停地演示简单,让注重概念,而不是与杂乱的代码定位

+0

谢谢charlietfl!您的实施是一个很好的工作,可以让我的黑客入门并使其更加优雅。我会尝试的另一个选择是使默认输出GET数据,但可以选择回拨。我会公布结果,但您的解决方案正是我所期待的。再次感谢! – user1032531 2013-03-16 20:49:54

+0

我的想法是只有那个..ideas ...可以使用服务器的数据做很多事情,可以设置插件内的选项来做事情...很多方法来改善它 – charlietfl 2013-03-16 20:51:52

+0

还有一个问题。请解释你对'this [type]()'的使用。 – user1032531 2013-03-16 20:52:30