Могу ли я настроить всплывающую подсказку в браузере? - PullRequest
4 голосов
/ 14 июля 2011

Являются ли они способом настроить вид всплывающих подсказок в браузере?

Например, при наведении указателя мыши на тег, имеющий атрибут 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. Огромная работа в процессе. Наведите курсор на любую из кнопок навигации для активного примера.

Ответы [ 7 ]

6 голосов
/ 14 июля 2011

Я просто хотел отметить, что всплывающая подсказка, отображаемая для заголовков, обычно встроена в операционную систему, и браузер не предоставляет интерфейс CSS для переопределения параметров операционной системы по умолчанию.

Часто,браузер даже не изменяет поведение этого внешнего вида для себя.

2 голосов
/ 14 июля 2011

В CSS нет ничего, что можно было бы использовать для настройки всплывающей подсказки. Вам придется использовать Javascript или любую другую инфраструктуру JS, чтобы достичь этого. В настоящее время существуют сотни различных фрагментов jQuery и Mootools, которые можно бесплатно загрузить и настроить в соответствии со своими потребностями.

1 голос
/ 14 июля 2011

Вы также можете начать с этой скрипки: http://jsfiddle.net/2RN6E/

И поставить больше CSS

1 голос
/ 14 июля 2011

Если вы не хотите использовать Javascript, вы можете добиться этого, используя чистый CSS. Однако могут быть некоторые ограничения. У всплывающей подсказки JS может быть больше возможностей.

Например, проверьте эти:

1 голос
/ 14 июля 2011

Мне неизвестны какие-либо расширения браузеров для CSS, которые позволили бы вам настраивать вид подсказок.

Существует множество плагинов для всплывающих подсказок jQuery, например,

Вы можете применить его ко всем элементам HTML с атрибутом title, например:

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

(Не уверен, насколько хорошо он будет работать.)

0 голосов
/ 14 июля 2011

Вы также можете попробовать это:

http://djgdesign.co.uk/display.php?id=47

Это работает, используя div и помещая его рядом с курсором:)

0 голосов
/ 14 июля 2011

Конечно, я разработал этот плагин для 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...