Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Всплывающая подсказка (https://javascript.ru/forum/jquery/80499-vsplyvayushhaya-podskazka.html)

Сергей Ракипов 13.06.2020 12:31

Всплывающая подсказка
 
Я пока не знаю эту библиотеку, и нашел вот такой скрипт.

/*
 * jQuery Tooltip plugin 1.3
 *
 * [url]http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/[/url]
 * [url]http://docs.jquery.com/Plugins/Tooltip[/url]
 *
 * Copyright (c) 2006 - 2008 Jörn Zaefferer
 *
 * $Id: jquery.tooltip.js 5741 2008-06-21 15:22:16Z joern.zaefferer $
 * 
 * Dual licensed under the MIT and GPL licenses:
 *   [url]http://www.opensource.org/licenses/mit-license.php[/url]
 *   [url]http://www.gnu.org/licenses/gpl.html[/url]
 */
 
;(function($) {
	
		// the tooltip element
	var helper = {},
		// the current tooltipped element
		current,
		// the title of the current element, used for restoring
		title,
		// timeout id for delayed tooltips
		tID,
		// IE 5.5 or 6
		IE = $.browser.msie && /MSIE\s(5\.5|6\.)/.test(navigator.userAgent),
		// flag for mouse tracking
		track = false;
	
	$.tooltip = {
		blocked: false,
		defaults: {
			delay: 200,
			fade: false,
			showURL: true,
			extraClass: "",
			top: 15,
			left: 15,
			id: "tooltip"
		},
		block: function() {
			$.tooltip.blocked = !$.tooltip.blocked;
		}
	};
	
	$.fn.extend({
		tooltip: function(settings) {
			settings = $.extend({}, $.tooltip.defaults, settings);
			createHelper(settings);
			return this.each(function() {
					$.data(this, "tooltip", settings);
					this.tOpacity = helper.parent.css("opacity");
					// copy tooltip into its own expando and remove the title
					this.tooltipText = this.title;
					$(this).removeAttr("title");
					// also remove alt attribute to prevent default tooltip in IE
					this.alt = "";
				})
				.mouseover(save)
				.mouseout(hide)
				.click(hide);
		},
		fixPNG: IE ? function() {
			return this.each(function () {
				var image = $(this).css('backgroundImage');
				if (image.match(/^url\(["']?(.*\.png)["']?\)$/i)) {
					image = RegExp.$1;
					$(this).css({
						'backgroundImage': 'none',
						'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
					}).each(function () {
						var position = $(this).css('position');
						if (position != 'absolute' && position != 'relative')
							$(this).css('position', 'relative');
					});
				}
			});
		} : function() { return this; },
		unfixPNG: IE ? function() {
			return this.each(function () {
				$(this).css({'filter': '', backgroundImage: ''});
			});
		} : function() { return this; },
		hideWhenEmpty: function() {
			return this.each(function() {
				$(this)[ $(this).html() ? "show" : "hide" ]();
			});
		},
		url: function() {
			return this.attr('href') || this.attr('src');
		}
	});
	
	function createHelper(settings) {
		// there can be only one tooltip helper
		if( helper.parent )
			return;
		// create the helper, h3 for title, div for url
		helper.parent = $('<div id="' + settings.id + '"><span class="title"></span><div class="body"></div><div class="url"></div></div>')
			// add to document
			.appendTo(document.body)
			// hide it at first
			.hide();
			
		// apply bgiframe if available
		if ( $.fn.bgiframe )
			helper.parent.bgiframe();
		
		// save references to title and url elements
		helper.title = $('span', helper.parent);
		helper.body = $('div.body', helper.parent);
		helper.url = $('div.url', helper.parent);
	}
	
	function settings(element) {
		return $.data(element, "tooltip");
	}
	
	// main event handler to start showing tooltips
	function handle(event) {
		// show helper, either with timeout or on instant
		if( settings(this).delay )
			tID = setTimeout(show, settings(this).delay);
		else
			show();
		
		// if selected, update the helper position when the mouse moves
		track = !!settings(this).track;
		$(document.body).bind('mousemove', update);
			
		// update at least once
		update(event);
	}
	
	// save elements title before the tooltip is displayed
	function save() {
		// if this is the current source, or it has no title (occurs with click event), stop
		if ( $.tooltip.blocked || this == current || (!this.tooltipText && !settings(this).bodyHandler) )
			return;

		// save current
		current = this;
		title = this.tooltipText;
		
		if ( settings(this).bodyHandler ) {
			helper.title.hide();
			var bodyContent = settings(this).bodyHandler.call(this);
			if (bodyContent.nodeType || bodyContent.jquery) {
				helper.body.empty().append(bodyContent)
			} else {
				helper.body.html( bodyContent );
			}
			helper.body.show();
		} else if ( settings(this).showBody ) {
			var parts = title.split(settings(this).showBody);
			helper.title.html(parts.shift()).show();
			helper.body.empty();
			for(var i = 0, part; (part = parts[i]); i++) {
				if(i > 0)
					helper.body.append("<br/>");
				helper.body.append(part);
			}
			helper.body.hideWhenEmpty();
		} else {
			helper.title.html(title).show();
			helper.body.hide();
		}
		
		// if element has href or src, add and show it, otherwise hide it
		if( settings(this).showURL && $(this).url() )
			helper.url.html( $(this).url().replace('http://', '') ).show();
		else 
			helper.url.hide();
		
		// add an optional class for this tip
		helper.parent.addClass(settings(this).extraClass);

		// fix PNG background for IE
		if (settings(this).fixPNG )
			helper.parent.fixPNG();
			
		handle.apply(this, arguments);
	}
	
	// delete timeout and show helper
	function show() {
		tID = null;
		if ((!IE || !$.fn.bgiframe) && settings(current).fade) {
			if (helper.parent.is(":animated"))
				helper.parent.stop().show().fadeTo(settings(current).fade, current.tOpacity);
			else
				helper.parent.is(':visible') ? helper.parent.fadeTo(settings(current).fade, current.tOpacity) : helper.parent.fadeIn(settings(current).fade);
		} else {
			helper.parent.show();
		}
		update();
	}
	
	/**
	 * callback for mousemove
	 * updates the helper position
	 * removes itself when no current element
	 */
	function update(event)	{
		if($.tooltip.blocked)
			return;
		
		if (event && event.target.tagName == "OPTION") {
			return;
		}
		
		// stop updating when tracking is disabled and the tooltip is visible
		if ( !track && helper.parent.is(":visible")) {
			$(document.body).unbind('mousemove', update)
		}
		
		// if no current element is available, remove this listener
		if( current == null ) {
			$(document.body).unbind('mousemove', update);
			return;	
		}
		
		// remove position helper classes
		helper.parent.removeClass("viewport-right").removeClass("viewport-bottom");
		
		var left = helper.parent[0].offsetLeft;
		var top = helper.parent[0].offsetTop;
		if (event) {
			// position the helper 15 pixel to bottom right, starting from mouse position
			left = event.pageX + settings(current).left;
			top = event.pageY + settings(current).top;
			var right='auto';
			if (settings(current).positionLeft) {
				right = $(window).width() - left;
				left = 'auto';
			}
			helper.parent.css({
				left: left,
				right: right,
				top: top
			});
		}
		
		var v = viewport(),
			h = helper.parent[0];
		// check horizontal position
		if (v.x + v.cx < h.offsetLeft + h.offsetWidth) {
			left -= h.offsetWidth + 20 + settings(current).left;
			helper.parent.css({left: left + 'px'}).addClass("viewport-right");
		}
		// check vertical position
		if (v.y + v.cy < h.offsetTop + h.offsetHeight) {
			top -= h.offsetHeight + 20 + settings(current).top;
			helper.parent.css({top: top + 'px'}).addClass("viewport-bottom");
		}
	}
	
	function viewport() {
		return {
			x: $(window).scrollLeft(),
			y: $(window).scrollTop(),
			cx: $(window).width(),
			cy: $(window).height()
		};
	}
	
	// hide helper and restore added classes and the title
	function hide(event) {
		if($.tooltip.blocked)
			return;
		// clear timeout if possible
		if(tID)
			clearTimeout(tID);
		// no more current element
		current = null;
		
		var tsettings = settings(this);
		function complete() {
			helper.parent.removeClass( tsettings.extraClass ).hide().css("opacity", "");
		}
		if ((!IE || !$.fn.bgiframe) && tsettings.fade) {
			if (helper.parent.is(':animated'))
				helper.parent.stop().fadeTo(tsettings.fade, 0, complete);
			else
				helper.parent.stop().fadeOut(tsettings.fade, complete);
		} else
			complete();
		
		if( settings(this).fixPNG )
			helper.parent.unfixPNG();
	}
	
})(jQuery);




Он создаете подсказку, но проблема в том что при изменение размера окна, он работает коряво, а именно подсказку жестко смещает вправо и е не видно.
Не могу сообразить, как сделать что бы подсказка всегда сплавало по центу объекта на который наводишь, и была либо сверху когда досточно место для отображение содержание подсказки, (бывают большие картинки) либо снизу объекта на который наводишь если сверху нету места, но не по бокам.

Сергей Ракипов 13.06.2020 12:38

Или вот еще нашел, но что бы в него можно было картинки вставлять

! function($, b, c, d) {
    'use strict';
    $.fn.liteTooltip = function(c) {
        var g, e = $(this),
            f = $.extend({}, $.fn.liteTooltip.default, c);
		e.each(function() {
			
			var evnt = ( typeof $(this).attr('data-tooltip-mouseover') !== 'undefined' ) ? 'mouseover' : ( typeof $(this).attr('data-tooltip-focus') !== 'undefined' ) ? 'focus' : 'mouseover';
			'mouseover' === evnt ? g = 'mouseout' : 'focus' === evnt && (g = 'blur')
			
            $(this).on(evnt, function() {
				$.fn.liteTooltip.removeElem(f)
                function m($) {
                    'top' === $.position ? r($) : 'left' === $.position ? p($) : 'right' === $.position ? o($) : 'bottom' === $.position ? q($) : n($), t($, i)
                }

                function n(c) {
                    function t($, b) {
                        'top' === $ ? (b.position = 'top', r(b)) : 'bottom' === $ ? (b.position = 'bottom', q(b)) : 'left' === $ ? (b.position = 'left', p(b)) : 'right' === $ && (b.position = 'right', o(b))
                    }
                    var d = {
                            left: 0,
                            right: 0,
                            top: 0,
                            bottom: 0
                        },
                        e = null,
                        g = 0,
                        h = c.triggerLeft - c.tlWidth + f.space;
                    h > g && (d.left = h);
                    var i = $(b).width(),
                        j = i - (c.triggerLeft + c.triggerW);
                    j > c.tlWidth && (d.right = j);
                    var k = c.triggerTop,
                        l = k;
                    l > c.tlHeight + f.space && (d.top = l);
                    var m = $(b).height(),
                        n = m - (c.triggerTop + c.triggerH);
                    n > c.tlHeight + f.space && (d.bottom = n);
                    var s = Math.max(d.left, d.right, d.top, d.bottom);
                    $.each(d, function($, b) {
                        b === s && (e = $)
                    }), t(e, c)
                }

                function o(c) {
                    var d = $(b).width(),
                        e = d - (c.triggerLeft + c.triggerW);
                    if (e < c.tlWidth + f.space) n(c);
                    else {
                        var g = u(c, 'sideRight'),
                            h = v(c);
                        s(h, g)
                    }
                }

                function p($) {
                    if ($.triggerLeft < $.tlWidth + f.space) n($);
                    else {
                        var b = u($, 'sideLeft'),
                            c = v($);
                        s(c, b)
                    }
                }

                function q(c) {
                    var d = $(b).height(),
                        e = d - (c.triggerTop + c.triggerH);
                    if (e < c.tlHeight + f.space) n(c);
                    else {
                        var g = u(c),
                            h = c.triggerTop + c.triggerH + f.space;
                        s(h, g)
                    }
                }

                function r($) {
                    if ($.triggerTop < $.tlHeight + f.space) n($);
                    else {
                        var b = u($),
                            c = $.triggerTop - $.tlHeight - f.space;
                        s(c, b)
                    }
                }

                function s(b, c) {
                    $('#tooltip').css({
                        top: b,
                        left: c
                    })
                }

                function t(b, c) {
                    c.bool ? 'top' === b.position ? 'left' === c.side ? (x('left', b), $('#tooltip').find('.tooltip-arrow').css({
                        left: b.triggerW / 2 - 8
                    })) : 'right' === c.side && (x('right', b), $('#tooltip').find('.tooltip-arrow').css({
                        left: b.tlWidth - (b.triggerW - 8)
                    })) : 'bottom' === b.position && ('left' === c.side ? (x('left', b), $('#tooltip').find('.tooltip-arrow').css({
                        left: b.triggerW / 2 - 8
                    })) : 'right' === c.side && (x('right', b), $('#tooltip').find('.tooltip-arrow').css({
                        left: b.triggerW + 8
                    }))) : x('center', b)
                }

                function u(c, d) {
                    if (d && 'sideLeft' === d) var e = c.triggerLeft - (c.tlWidth + f.space);
                    else if (d && 'sideRight' === d) var e = c.triggerLeft + (c.triggerW + f.space);
                    else var g = .5 * c.tlWidth - .5 * c.triggerW,
                        e = c.triggerLeft - g;
                    return e < 0 ? (e = c.triggerLeft, i.bool = !0, i.side = 'left') : e > $(b).width() && (e = $(b).width() - (c.triggerLeft + c.triggerW) - c.tlWidth, i.bool = !0, i.side = 'right'), e
                }

                function v($) {
                    var b = .5 * $.tlHeight - .5 * $.triggerH,
                        c = $.triggerTop - b;
                    return c < 0 && (c = $.triggerTop), c
                }

                function w() {
                    var b = $('<div class="tooltip animation-' + f.animation + '" id="tooltip"></div>');
                    $('body').append(b)
                }

                function x(b, c) {
                    var d, e;
                    'left' === b ? 'top' === c.position ? e = 'toptobottom' : 'bottom' === c.position && (e = 'bottomtotop') : 'right' === b ? 'top' === c.position || 'bottom' === c.position : b && 'center' !== b || ('top' === c.position ? e = 'toptobottom center' : 'bottom' === c.position && (e = 'bottomtotop center')), 'left' === c.position ? e = 'lefttoright' : 'right' === c.position && (e = 'righttoleft'), d = $('<div class="tooltip-arrow ' + e + ' "></div>'), $('#tooltip').append(d)
                }
                var c = $(this),
                    e = c.data( 'tooltip' + evnt[0].toUpperCase() + evnt.substring(1) ),
                    g = c.data('tooltipPosition') === d || '' === c.data('tooltipPosition') ? f.position : c.data('tooltipPosition'),
                    h = !1,
                    i = {
                        bool: !1,
                        side: ''
                    },
                    j = c.offset();				
                if (h = e !== d && '' !== e && null !== e) {
                    w();
                    var k = $('#tooltip');
                    k.html(e);
                    var l = {
                        triggerW: parseInt(c.width()) + parseInt(c.css('padding-left')) + parseInt(c.css('padding-right')),
                        triggerH: parseInt(c.height()) + parseInt(c.css('padding-top')) + parseInt(c.css('padding-bottom')),
                        triggerTop: j.top,
                        triggerLeft: j.left,
                        tlWidth: k.width() + parseInt(k.css('padding-left')) + parseInt(k.css('padding-right')),
                        tlHeight: k.height() + parseInt(k.css('padding-top')) + parseInt(k.css('padding-bottom')),
                        position: g
                    };
                    m(l)
                }
            }).on(g, function() {
                $.fn.liteTooltip.removeElem(f)
            })
        })
    }, $.fn.liteTooltip.removeElem = function(b) {
        $('body').find('#tooltip').length > 0 && $('#tooltip').removeClass('animation-' + b.animation).fadeOut(50).remove()
    }, $.fn.liteTooltip.default = {
        space: 20,
        animation: 'slide',
        position: 'top',
    }
}(jQuery, window, document);
$('.liteTooltip').liteTooltip();

рони 13.06.2020 13:50

Сергей Ракипов,
https://api.jqueryui.com/tooltip/

параметр position

Сергей Ракипов 13.06.2020 15:34

рони,
Спасибо попробуй разобраться, но думаю может проще самому написать, вроде бы не должно быть сложно.

Сергей Ракипов 18.06.2020 16:39

Так и не разобрался видимо пока знаний и не хватать, решил сам написать, и получилось на половину.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=script, initial-scale=1.0">
    <title>Document</title>
    <style>
        body{
	font-family: Verdana, Geneva CY, Helvetica, DejaVu Sans, Arial, sans-serif;
	font-size: .8rem;
	line-height: 160%;
}
a{
	color: #000;
	text-decoration: none;
}
a:hover{
	color: cornflowerblue;
	text-decoration: underline;
}
.blok{
	margin: 640px auto 640px;
	max-width: 720px;
}
.zagalovok{
	font: 2rem/0rem
}
.tekst{
	font: 1rem/1rem
}
.shriht{
	position: relative;
	margin: 0px 0px 5px 0px;
	width: 280px;
	/* text-align: center; */
}
.kartinka_pri_navedenii{
	position: absolute;
	top: 0px;
	left: 280px;
	border: 10px solid #2e2e2e;
	box-sizing: border-box;
	line-height: 0px;
	opacity: 0;
	transition: opacity .2s;
}
    </style>
</head>
<body>

<div class="blok">
    <div class="shriht">
        <a href="03_ubuntu_didact_gothic/" target="_blank">Ubuntu & Didact Gothic</a>
    
    </div>

    <div class="shriht">
        <a href="04_spectral_source_sans_pro/" target="_blank">Spectral & Source Sans Pro</a>
    
    </div>

    <div class="shriht">
        <a href="05_source_sans_pro_source_serif_pro/" target="_blank">Source Sans Pro & Source Serif Pro</a>
    
    </div>

    <div class="shriht">
        <a href="06_rubik_rubik/" target="_blank">Rubik & Rubik</a>
    
    </div>

    <div class="shriht">
        <a href="07_roboto_slab_roboto/" target="_blank">Roboto & Roboto Slab</a>
    
    </div>

    <div class="shriht">
        <a href="08_roboto_slab_open_sans/" target="_blank">Roboto Slab & Open Sans</a>
    
    </div>

    <div class="shriht">
        <a href="09_roboto_nunito/" target="_blank">Roboto Slab & Nunito</a>
    
    </div>

    <div class="shriht">
        <a href="10_raleway_merriweather/" target="_blank">Raleway & Merriweather</a>
    
    </div>

    <div class="shriht" id="navedenie">
        <a href="11_raleway/" target="_blank">Raleway & Raleway</a>
        <div class="kartinka_pri_navedenii">
            <img src="https://rakipov.ru/files/11.png" alt="">
        </div>
    </div>

    <div class="shriht">
        <a href="12_pt_serif_open_sans/" target="_blank">PT Serif & Open Sans</a>
    
    </div>

    <div class="shriht">
        <a href="13_pt_sans_pt_serif/" target="_blank">PT sans & PT serif</a>
    
    </div>

    <div class="shriht">
        <a href="14_pt_sans_didact_gothic/" target="_blank">PT sans & Didact Gothic</a>
    
    </div>

    <div class="shriht">
        <a href="15_playfair_display_open_sans/" target="_blank">Playfair Display & Open Sans</a>
    
    </div>

    <div class="shriht">
        <a href="16_playfair_display_alice/" target="_blank">Playfair Display & Alice</a>
    
    </div>
</div>
    <script>
"use_strict"

const navedenie = document.querySelector("#navedenie");
const kartinkaPriNavedenii = document.querySelector(".kartinka_pri_navedenii");

function priNavedenii_1() {
    let navedenie = document.querySelector("#navedenie");
    let test = navedenie.getBoundingClientRect();

    console.log(test.top);

    function priNavedenii_2() {

        if (test.top >= 387) {
            kartinkaPriNavedenii.style.opacity = "1";
            kartinkaPriNavedenii.style.top = "-387" + "px";
        } else if (test.top >= 0) {
            kartinkaPriNavedenii.style.opacity = "1";
            kartinkaPriNavedenii.style.top = "0" + "px";
        }
    }
    navedenie.addEventListener("mouseover", priNavedenii_2);
}
window.addEventListener('scroll', priNavedenii_1);


function priNavedenii_3(){
    kartinkaPriNavedenii.style.opacity = "0";

}
navedenie.addEventListener("mouseout", priNavedenii_3);
    </script>
</body>
</html>


И у меня сейчас сделано для одного блока, а их будет штук 50 как написать код для них всех, и функция логично начинает работать после скрола, а как сделать что бы даже если не был скрола она работала.


Нужно навестись на Raleway & Raleway

и она будет работать если есть место то покажет картинку сверху, если нет то снизу.

Сергей Ракипов 19.06.2020 13:33

Вот одну проблему решил, а именно что бы функция не ждала скролл Я написал

window.addEventListener('mousemove', priNavedenii_1);

Но на сколько это разумно? и не костыль ли это

рони 19.06.2020 16:29

Сергей Ракипов,
разумно mouseenter и mouseleave плюс делегирование, ещё разумнее css.

Сергей Ракипов 19.06.2020 17:08

Я читал про то и подумал что
mouseenter и mousemove это одно и тоже

и что такое делегирование

рони 19.06.2020 17:29

Сергей Ракипов,
делегирование - это обработка события не на каждом элементе, а на общем их родителе.
https://learn.javascript.ru/event-delegation

рони 19.06.2020 17:31

Цитата:

Сообщение от Сергей Ракипов
mouseenter и mousemove это одно и тоже

и что такое делегирование

https://javascript.ru/forum/events/8...tml#post525963


Часовой пояс GMT +3, время: 17:06.