2011-07-13 92 views
4

他們是如何自定義工具提示氣泡的方式,跨瀏覽器?我可以自定義瀏覽器中的工具提示泡泡嗎?

例如,當我將鼠標懸停在具有title屬性的標記上時,Firefox顯示工具提示泡泡。我想自定義它看起來就像網站的其他部分。

有沒有CSS3入侵?如果不是,我可以將它替換爲所有具有title屬性的元素都會自動運行的東西嗎?

<a href="" title="This is a nice link, click here"/> <div onclick="" title="A nice action button"/> 

形象的例子:

A nice example image of my site.

我讓我的網站良好的前瞻性和準備服務辛勤工作的實際。我注意到的一件事情是工具提示打破了我的風格,只是一點點...但我對這些東西很瘋狂。是的,我仍在努力 - http://pagelook.us。巨大的工作在進行中。將鼠標懸停在某個活動示例的任何導航按鈕上。

回答

0

當然,我開發了這個jQuery插件,你只需要包括在您的網頁

這裏是如何得到它的工作:http://plugins.jquery.com/project/jTitle

/*! jQuery Tooltip Plugin by Pezhvak @ IMVx.ORG 
* Version: 1.0 
* Tested on IE9, FF4, Safari5 
* Description: By using this plugin all of your title attributes going to change, you may even change your tooltips in runtime 
*/ 

(function($){ 
    /* 
    * @groupName: [string] name of the group of titlebox 
    * @ms: [milliseconds] to hide, if 0: hide when mouseout, if -1: don't hide automatically, if -2: hide when clicked on title 
    * @delay: [milliseconds] to show, -1: don't show automatically 
    * @mode: [string] how you want to manage your titles, single: only one toolbox allowed to be shown in each category, share: one toolbox will be shared between all elements in a group, free: each element have it's own titlebox 
    * @move: [string] how titlebox appears, vertically, horizontally or static. static: without moving effect 
    * @stop: [string] which side of the element titlebox should stop? on width or height? 
    * @showEasing: [string] what effect to use when titlebox appears, [easeOutBounce, easeOutElastic] 
    * @hideEasing: [string] what effect to use when titlebox disappears, [same as showEasing] 
    * @moveEasing: [string] what effect to use when titlebox is moving to other element, [same as showEasing], it will be used only when mode is 
    * @theme: [object] contains style of the titlebox 
    * ! Keep in mind you may override default settings for your special elements by setting [titleMS, titleMove, titleStop, titleShowEasing, titleHideEasing, titleTheme] attribute for them. 
    * ! titleTheme should contains created theme name by $.createTheme function 
    */ 
    var option = {groupName: '_default_', 
        ms: 5000, 
        speed: 'slow', 
        delay: 0, 
        distance: 'auto', 
        mode: 'single', 
        move: 'horizontally', 
        stop: 'width', 
        recommend: 'auto', 
        showEasing: 'easeOutBounce', 
        hideEasing: 'easeInOutBounce', 
        moveEasing: 'easeOutElastic', 
        theme:{ 
         shadow: '0px 0px 5px #292929', 
         opacity: 0.8, 
         roundCorners: 5, 
         style: { 
          color: '#fff', 
          background: 'rgba(0,0,0, 0.8)', 
          padding: '10px', 
          fontSize: '12px' 
         } 
        } 
    }; 
    var _idc = 0; // ID Counter 
    var groups = {}; 
    var currentGroup = {}; 

    $.titleDefineGroup = function(group_name, options) 
    { 
     var option_buffer = $.extend(true, {}, option); 
     groups[group_name] = $.extend(true, option_buffer, options); 
     groups[group_name].groupName = group_name; 
    } 

    function get_image_size(image_uri) 
    { 
     var image = new Image(); 
     image.src = image_uri; 
     return {width: image.width, height: image.height}; 
    } 

    $(window).bind('load.tooltip', function(){ 
     $("[title]").live('mouseover.tooltip', function(){ 
      _idc++; 
      $(this).attr('customTitle', $(this).attr('title')).attr('title', null).attr('_idc', _idc); 
      this.onTitleShow = function(){} // titleShowEvent 
      this.onTitleHide = function(){} // titleHideEvent 
      $(this).mouseover(); 
     }); 

     $("[customTitle]").live('mouseover.tooltip', function(){ 
      $(this).tooltip({text: $(this).attr("customTitle")}); 
     }); 
    }); 

    $.fn.onTitleShow = function(fnc) 
    { 
     return this.each(function(){ 
      this.onTitleShow = fcn; 
     }); 
    }; 

    $.fn.onTitleHide = function(fnc) 
    { 
     return this.each(function(){ 
      this.onTitleHide = fnc; 
     }); 
    }; 

    $.fn.showTitle = function() 
    { 
     return this.each(function(){ 
      if($(this).attr("customTitle")!="") 
      { 
       _idc++; 
       $(this).attr('customTitle', $(this).attr('title')).attr('title', null).attr('_idc', _idc); 
       this.onTitleShow = function(){} // titleShowEvent 
       this.onTitleHide = function(){} // titleHideEvent 
       $(this).tooltip({text: $(this).attr("customTitle"), forced: true}); 
      } 
     }); 
    } 

    $.titleSettings = function(options) 
    { 
     $.extend(true, option, options); 
    }; 

    function _tooltip_generate_arrow(side) 
    { 
     var canvas = document.createElement('canvas'); 
     if(!canvas.getContext) return; 
     var canvasContext = canvas.getContext('2d'); 
     canvasContext.beginPath(); 
     switch(side) 
     { 
      case "up":{ 
       canvas.width = '8'; 
       canvas.height = '6'; 

       canvasContext.moveTo(4,0); 
       canvasContext.lineTo(8,6); 
       canvasContext.lineTo(0,6); 
       canvasContext.lineTo(4,0); 

      }break; 
      case "down":{ 
       canvas.width = '8'; 
       canvas.height = '6'; 

       canvasContext.moveTo(4,6); 
       canvasContext.lineTo(0,0); 
       canvasContext.lineTo(8,0); 
       canvasContext.lineTo(4,6); 
      }break; 
      case "left":{ 
       canvas.width = '6'; 
       canvas.height = '8'; 

       canvasContext.moveTo(0,4); 
       canvasContext.lineTo(6,0); 
       canvasContext.lineTo(6,8); 
       canvasContext.lineTo(0,4); 
      }break; 
      case "right":{ 
       canvas.width = '6'; 
       canvas.height = '8'; 

       canvasContext.moveTo(6,4); 
       canvasContext.lineTo(0,0); 
       canvasContext.lineTo(0,8); 
       canvasContext.lineTo(6,4); 
      }break; 
     } 

     canvasContext.fillStyle = currentGroup.theme.style.background; 
     canvasContext.fill(); 
     canvas.style.position = 'absolute'; 
     $(canvas).fadeOut(1); 
     return canvas; 
    } 

    function _tooltip_conflict(element, tooltip) 
    { 
     var result = {left: false, right: false, top: false, bottom: false, leftPoint: {x: 0, y: 0, position: 'center'}, rightPoint: {x: 0, y: 0, position: 'center'}, topPoint: {x: 0, y: 0, position: 'center'}, bottomPoint: {x: 0, y: 0, position: 'center'}}; 
     var elementPosition = element.offset(); 
     var padding = parseInt(tooltip.css('padding').replace('px','')) * 2; 
     if(isNaN(padding)) padding = 0; 
     var tooltipWidth = tooltip.width() + padding; 
     var tooltipHeight = tooltip.height() + padding; 
     var arrow = ''; 

     // Checking left 
     arrow = _tooltip_generate_arrow('right'); 
     if(elementPosition.left - tooltipWidth - arrow.width < 0) result.left = true; 
     else{ 
      result.leftPoint.x = elementPosition.left - tooltipWidth - arrow.width; 
      result.leftPoint.y = (tooltipHeight > element.height()) ? elementPosition.top - (tooltipHeight/2) + (element.height()/2) : elementPosition.top + (element.height()/2) - (tooltipHeight/2); 
      if(result.leftPoint.y < 0) {result.leftPoint.y = elementPosition.top; result.leftPoint.position = 'top';} 
      if(result.leftPoint.y + tooltipHeight > $(window).height()) {result.leftPoint.y = elementPosition.top - (tooltipHeight - element.height()); result.leftPoint.position = 'bottom';} 
     } 
     // Checking Right 
     arrow = _tooltip_generate_arrow('left'); 
     if(elementPosition.left + element.width() + tooltipWidth + arrow.width > $(window).width()) result.right = true; 
     else{ 
      result.rightPoint.x = elementPosition.left + element.width() + arrow.width; 
      result.rightPoint.y = (tooltipHeight > element.height()) ? elementPosition.top - (tooltipHeight/2) + (element.height()/2) : elementPosition.top + (element.height()/2) - (tooltipHeight/2); 
      if(result.rightPoint.y < 0) {result.rightPoint.y = elementPosition.top; result.rightPoint.position = 'top';} 
      if(result.rightPoint.y > $(window).height()) {result.rightPoint.y = elementPosition.top - (tooltipHeight - element.height()); result.rightPoint.position = 'bottom';} 
     } 
     // Checking Up 
     arrow = _tooltip_generate_arrow('down'); 
     if(elementPosition.top - tooltipHeight - arrow.height < 0) result.top = true; 
     else{ 
      result.topPoint.x = (tooltipWidth > element.width()) ? elementPosition.left - (tooltipWidth/2) + (element.width()/2) : elementPosition.left + (element.width()/2) - (tooltipWidth/2); 
      result.topPoint.y = elementPosition.top - tooltipHeight - arrow.height; 
      if(result.topPoint.x < 0) {result.topPoint.x = elementPosition.left; result.topPoint.position = 'left';} 
      if(result.topPoint.x+tooltipWidth > $(window).width()) {result.topPoint.x = elementPosition.left - (tooltipWidth - element.width()); result.topPoint.position = 'right';} 
     } 
     // Checking Down 
     arrow = _tooltip_generate_arrow('up'); 
     if(elementPosition.top + element.height() + tooltipHeight + arrow.height > $(window).height()) result.bottom = true; 
     else{ 
      result.bottomPoint.x = (tooltipWidth > element.width()) ? elementPosition.left - (tooltipWidth/2) + (element.width()/2) : elementPosition.left + (element.width()/2) - (tooltipWidth/2); 
      result.bottomPoint.y = elementPosition.top + element.height() + arrow.height; 
      if(result.bottomPoint.x < 0) {result.bottomPoint.x = elementPosition.left; result.bottomPoint.position = 'left';} 
      if(result.bottomPoint.x+tooltipWidth > $(window).width()) {result.bottomPoint.x = elementPosition.left - (tooltipWidth - element.width()); result.bottomPoint.position = 'right';} 
     } 

     return result; 
    } 

    function _tooltip_get_box_position() 
    { 

    } 

    $.tooltip_proccess = function(){ 
     // Define 
     $("[title]:not([titleGroup])").attr("titleGroup", "_default_"); 
     var settings = {move: 0, stop: 0, mode: 'single', recommend: 'auto', group: 'default', startPoint: {x: 0, y: 0}, endPoint: {x: 0, y: 0}} 
     settings.group = (($(this).attr("titleGroup")) ? (groups[$(this).attr("titleGroup")]) ? groups[$(this).attr("titleGroup")] : option : option); 
     currentGroup = settings.group; 
     settings.move = (($(this).attr("titleMove")) ? $(this).attr("titleMove") : settings.group.move).toLowerCase(); 
     settings.stop = (($(this).attr("titleStop")) ? $(this).attr("titleStop") : settings.group.stop).toLowerCase(); 
     settings.recommend = (($(this).attr("titleRecommend")) ? $(this).attr("titleRecommend") : settings.group.recommend).toLowerCase(); 

     // Verifying 
     if($(this).attr("titleActive")=="true") return; // prevent re-generation for elements which already have an active toolbox 

     if(settings.group.mode != 'free') 
     { 
      var force_return = false; 
      $("[titleGroup='"+$(this).attr("titleGroup")+"'][titleActive='true']").each(function(){ 
       clearTimeout(document.getElementById("toolbox_"+this.id).tooltipTimeout); // prepair to move 
       clearInterval(this.onTitleChange); 
       $("#toolbox_"+this.id).attr("titleActive", "false"); 
       if(settings.group.mode == 'single') 
       { 
        this.hideTitle(); 
       } 
       else // share 
       { 
        force_return = true; // we goint to handle it from here, we don't need rest of the code ;) 
        var elementPos = $(this).offset(); 
        var conflict = _tooltip_conflict($(this), $("#toolbox_"+this.id)); 
        var padding = parseInt(($("#toolbox_"+this.id).css("padding")).replace("px", "")); 
        var DIV = document.getElementById("toolbox_"+this.id); 

        //end 
       } 
      }); 
      if(force_return) return; 
     } 

     // Generating TooltipBox 
     $(this).attr("titleActive", "true"); 
     _idc++; 
     var DIV = document.createElement("DIV"); 
     if($(this).attr("id") == "") $(this).attr("id", "auto_"+_idc); 
     DIV.name = DIV.id = "toolbox_"+$(this).attr("id"); 
     DIV.style.position = 'absolute'; 
     $.extend(true, DIV.style, settings.group.theme.style); 
     DIV.style.background = settings.group.theme.style.background; 

     DIV.style.zIndex = 999; 
     DIV.innerHTML = $(this).attr("customTitle"); 
     this.onTitleChange = setInterval(function(){ 
      if($(_this).attr("customTitle") != DIV.childNodes[0].nodeValue) DIV.childNodes[0].nodeValue = $(_this).attr("customTitle"); 
     }, 100); 

     DIV.style.width = 'auto'; 
     DIV.style.height = 'auto'; 
     DIV.style.whiteSpace = 'nowrap'; 

     DIV.style['-moz-box-shadow'] = settings.group.theme.shadow; 
     DIV.style['-webkit-box-shadow'] = settings.group.theme.shadow; 
     DIV.style['box-shadow'] = settings.group.theme.shadow; 



     if(typeof(settings.group.theme.roundCorners) != 'number') settings.group.theme.roundCorners = settings.group.theme.roundCorners.replace(/px$/i, ''); 
     $(DIV).fadeTo(1,1).attr('_tidc', $(this).attr('_idc')).roundCorners(settings.group.theme.roundCorners); 
     document.body.appendChild(DIV); 

     // Determining 

     var elementPos = $(this).offset(); 
     var conflict = _tooltip_conflict($(this), $(DIV)); 
     var padding = parseInt(($(DIV).css("padding")).replace("px", "")); 

     // Adjusting Box 
     switch(settings.stop) 
     { 
      case "width": 
      { 
       switch(settings.recommend) 
       { 
        case "up": 
        case "top": 
        { 
         if(conflict.top) settings.recommend = 'bottom'; 
        }break; 
        case "down": 
        case "bottom": 
        { 
         if(conflict.bottom) settings.recommend = 'top'; 
        }break; 
        default: // Auto 
        { 
         settings.recommend = (elementPos.top < $(window).height()/2) ? 'bottom' : 'top'; 
        }break; 
       } 

       if(settings.move == 'vertically') 
       { 
        settings.startPoint.x = conflict[settings.recommend+'Point'].x; 
        settings.startPoint.y = settings.startPoint.y = (elementPos.top < $(window).height()/2) ? ($(window).height()/3) * 2 : ($(window).height()/3); 
       } 
       else 
       { 
        settings.startPoint.x = (elementPos.left < $(window).width()/2) ? ($(window).width()/3) * 2 : ($(window).width()/3); 
        settings.startPoint.y = conflict[settings.recommend+'Point'].y; 
       } 
       settings.endPoint.x = conflict[settings.recommend+'Point'].x; 
       settings.endPoint.y = conflict[settings.recommend+'Point'].y; 
      }break; 
      default: 
      case "height": 
      { 
       switch(settings.recommend) 
       { 
        case "left": 
        { 
         if(conflict.left) settings.recommend = 'right'; 
        }break; 
        case "right": 
        { 
         if(conflict.right) settings.recommend = 'left'; 
        }break; 
        default: // Auto 
        { 
         settings.recommend = (elementPos.left < $(window).width()/2) ? 'right' : 'left'; 
        }break; 
       } 
       if(settings.move == 'vertically') 
       { 
        settings.startPoint.x = conflict[settings.recommend+'Point'].x; 
        settings.startPoint.y = settings.startPoint.y = (settings.recommend == 'bottom') ? ($(window).height()/3) * 2 : ($(window).height()/3); 
       } 
       else 
       { 
        settings.startPoint.x = (elementPos.left < $(window).width()/2) ? ($(window).width()/3) * 2 : ($(window).width()/3); 
        settings.startPoint.y = conflict[settings.recommend+'Point'].y; 
       } 

       settings.endPoint.x = conflict[settings.recommend+'Point'].x; 
       settings.endPoint.y = conflict[settings.recommend+'Point'].y; 
      }break; 
     } 

     // Setting up distance 
     if(typeof(settings.group.distance) == "string") 
      settings.group.distance = settings.group.distance.replace(/px$/gi, ''); 

     if(settings.startPoint.x != settings.endPoint.x && settings.group.distance != 'auto') // horizontal move 
     { 
      var res = settings.endPoint.x - settings.startPoint.x; 
      if(res < 0) // tooltip is moving to left 
       settings.startPoint.x = parseInt(settings.endPoint.x) + parseInt(settings.group.distance); 
      else // tooltip is moving to right 
       settings.startPoint.x = parseInt(settings.endPoint.x) - parseInt(settings.group.distance); 
     } 

     if(settings.startPoint.y != settings.endPoint.y && settings.group.distance != 'auto') // vertical move 
     { 
      var res = settings.endPoint.y - settings.startPoint.y; 
      if(res < 0) // tooltip is moving to top 
       settings.startPoint.y = parseInt(settings.endPoint.y) + parseInt(settings.group.distance); 
      else // tooltip is moving to bottom 
       settings.startPoint.y = parseInt(settings.endPoint.y) - parseInt(settings.group.distance); 
     } 


     // Adjusting Arrow 
     var arrow = ''; 

     switch(settings.recommend) 
     { 
      case "top": 
      { 
       arrow = _tooltip_generate_arrow("down"); 
       arrow.style.top = (DIV.offsetHeight-1)+"px"; 
       arrow.style.left = ((DIV.offsetWidth/2) - (arrow.width/2))+"px"; 
      }break 
      case "bottom": 
      { 
       arrow = _tooltip_generate_arrow("up"); 
       arrow.style.top = "-"+arrow.height+"px"; 
       arrow.style.left = ((DIV.offsetWidth/2) - (arrow.width/2))+"px"; 
      }break 
      case "left": 
      { 
       arrow = _tooltip_generate_arrow("right"); 
       arrow.style.top = ((DIV.offsetHeight/2) - arrow.height/2)+"px"; 
       arrow.style.left = (DIV.offsetWidth)+"px"; 
      }break 
      case "right": 
      { 
       arrow = _tooltip_generate_arrow("left"); 
       arrow.style.top = ((DIV.offsetHeight/2) - arrow.height/2)+"px"; 
       arrow.style.left = "-"+arrow.width+"px"; 
      }break 
     } 
     arrow.id = "tooltip_arrow_"+$(this).attr("id"); 

     var position = conflict[settings.recommend+'Point'].position; 
     switch(position) // by default (if no conflict happends) it will be center, usually it will change when tooltip box is grater than element in size 
     { 
      case "bottom": 
      { 
       arrow.style.top = ($(DIV).height() - ($(this).height()/2-arrow.height/2))+"px"; 
      }break; 
      case "top": 
      { 
       arrow.style.top = ($(this).height()/2-arrow.height/2)+"px"; 
      }break; 
      case "left": 
      { 
       arrow.style.left = ($(this).width()/2-arrow.width/2)+"px"; 
      }break; 
      case "right": 
      { 
       arrow.style.left = ($(DIV).width() - ($(this).width()/2 + arrow.width/2))+"px"; 
      }break; 
     } 
     // Appending Arrow To Box 
     DIV.appendChild(arrow); 

     // Moving Box 
     opts = $.extend({left: settings.endPoint.x, top: settings.endPoint.y}, {opacity: 1}); 
     var element = $(this); 
     var _this = this; 

     this.hideTitle = function() 
     { 
      opts = $.extend({left: $(DIV).attr("startX"), top: $(DIV).attr("startY")}, {opacity: 0}); 
      $(DIV).animate(opts, {duration: settings.group.speed, easing: settings.group.hideEasing, complete: function(){if(!isNaN(DIV)) document.body.removeChild(DIV); element.attr("titleActive", "false");}}); 
      this.onTitleHide.call(this); 
      clearInterval(this.onTitleChange); 
     } 

     this.onTitleShow(); 
     $(DIV).css({top: settings.startPoint.y, left: settings.startPoint.x}).animate(opts,{ 
      duration: settings.group.speed, 
      easing: settings.group.showEasing, 
      complete: function(){ 
       $(this).attr("startX", settings.startPoint.x).attr("startY", settings.startPoint.y); 
       switch(settings.group.ms.toString()) 
       { 
        case '0': // mouseout 
        { 
         element.bind('mouseout.tooltip', function(){ 
          _this.hideTitle(); 
         }); 
        }break; 
        case '-1':// manual 
        { 

        }break; 
        case '-2':// manual 
        { 
         $(DIV).bind('click.tooltip', function(){ 
          _this.hideTitle(); 
         }); 
        }break; 
        default: 
        { 
         DIV.tooltipTimeout = setTimeout(function(){ 
          _this.hideTitle(); 
         }, settings.group.ms); 
        }break; 
       } 

      } 
     }); 
    } 

    $.fn.tooltip = function(options){ 
     return this.each(function(){ 
      $(this).attr("delay", 'true').bind("mouseout.tooltip", function(){$(this).attr("delay", "false"); clearTimeout(this.delayTimeout);}); 
      var _this = this; 
      var group = (($(this).attr("titleGroup")) ? (groups[$(this).attr("titleGroup")]) ? groups[$(this).attr("titleGroup")] : option : option); 
      if(options.forced == true) $.tooltip_proccess.call(_this); 
      if(group.delay == -1) return; 
      _this.delayTimeout = setTimeout(function(){ 
       if($(_this).attr("delay") == "true") 
        $.tooltip_proccess.call(_this); 
      }, group.delay); 
     }); 
    }; 
})(jQuery) 
2

沒有什麼對CSS,可以用於定製工具提示。你將不得不使用Javascript或任何其他JS框架來達到。目前,有數百個不同的jQuery和Mootools代碼片斷,您可以免費下載並根據自己的需要進行自定義。

1

定位它,我不知道任何瀏覽器擴展到CSS的那讓你自定義工具提示的外觀。

雖然有很多jQuery工具提示插件,例如

你可以將其與title屬性這樣適用於所有的HTML元素:(不知道它會如何執行)

$("*[title]").tooltip(); 

+0

謝謝,但我試圖限制正在加載的JavaScript的數量,添加另一個框架會增加我的問題。我希望界面快速加載,以便用戶可以直接進入甜蜜的東西。但是所有的Ajax都在......我不得不將這添加到可能的更改列表中......哈哈。謝謝。 – JustinKaz

+0

@Justin:當然,可以理解。如果您已經在使用其他JavaScript框架,我相信它可以提供類似的功能。對於簡單的工具提示,[ChristopheCVB的建議](http://stackoverflow.com/questions/6684905/can-i-customize-the-in-browser-tool-tip-bubble/6685058#6685058)值得嘗試。 –

+0

Nop!我試圖使用所有我自己的JavaScript來輕鬆訪問,編碼標準,所以我可以控制使用什麼(等等)。網絡服務非常複雜,即使它看起來還沒有完成(這是因爲它,大聲笑)。 – JustinKaz

1

你也可以開始與小提琴: http://jsfiddle.net/2RN6E/

而把更多的CSS

+0

應該在答案本身中顯示一些代碼。如果有的話,你也不解釋實際發生了什麼,爲什麼你應該這樣做。更好的答案是「這是不可能的」,然後解釋一個替代方案。 – Jared

6

我只是想要指出的是,爲標題顯示的工具提示通常是內置在操作系統中的工具提示,並且瀏覽器不提供用於覆蓋操作系統默認值的CSS界面。

通常,瀏覽器甚至不會修改該外觀和行爲本身的行爲。

+0

我不同意這一點。工具提示的寬度和包裝行爲因瀏覽器而異。試試這個[JsFiddle](https://jsfiddle.net/5c8hL0ap/)與IE,Firefox,Chrome甚至Edge ... –

+0

你會注意到我在2011年寫了這個答案,當時鉻不存在。即使句子的第一部分不再成立,第二點和總體點仍然是相同的。 – Jordan

+1

何是我沒注意日期對不起。然而,Chrome的第一個穩定版本是在2008年推出的... –

相關問題