2013-03-16 98 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