移动友好的工具提示在 Android 浏览器中不起作用

Posted

技术标签:

【中文标题】移动友好的工具提示在 Android 浏览器中不起作用【英文标题】:Mobile-friendly tooltip not working in Android browser 【发布时间】:2014-08-16 08:59:11 【问题描述】:

我想为我的网站制作一个工具提示,并找到了一个很好的解决方案:http://osvaldas.info/elegant-css-and-jquery-tooltip-responsive-mobile-friendly。

他们说它对移动设备友好。它在我的 ipad 上运行良好,但在我的 android(如果需要,HTC Wildfire)网络浏览器中它不起作用(它的反应方式就像是一段简单的文本)。

1) 是什么原因,Android 有什么特别之处? 2) 如何解决以及如何使工具提示对两种移动操作系统都适用?

【问题讨论】:

如果可以的话,请粘贴一些代码并解释您到目前为止所做的尝试。除了解决方案本身之外,您自己的代码似乎有问题。 【参考方案1】:

"1) 是什么原因,Androids有什么特别之处?" FC:很多,但我想不出这能解释你的问题。不是没有进一步说明您的问题。

“2) 如何解决这个问题以及如何使工具提示对两个移动操作系统都友好。” FC:幸运的是,这很容易。使用非常简单的原生/香草 javascript 和一些简单的嵌套跨度:live demo;使用代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Light-weight Tooltip by FC</title>
<style>
    html 
        font-size: 62.5%;
    
    body 
        font: normal 1.3em Verdana;
        background-color: white;
        /* just for the JSBin demo */
    
    h2 
        text-align: center;
        margin-bottom: 2em;
    
    span.tool 
        position: relative;
        display: inline-block;
        border-bottom: 1px dotted black;
    
    span.tool:hover 
        cursor: help;
    
    span.tip 
        position: absolute;
        bottom: 20px;
        left: 0px;
        display: block;
        width: auto;
        white-space: nowrap;
        font-size: .9em;
        border: 0px solid black; /* change as desired */
        border-radius: 6px;
        padding: 1px 5px;
        background: #eee;
        background: linear-gradient(top, #eee, #ccc);
        background: -moz-linear-gradient(top, #eee, #ccc);
        background: -o-linear-gradient(top, #eee, #ccc);
        background: -webkit-linear-gradient(top, #eee, #ccc);
        background: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#ccc));
        background: -ms-linear-gradient(top, #eee, #ccc);
        filter: progid: DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr=#eeeeee, EndColorStr=#cccccc);
        zoom: 1;
        visibility: hidden;
    
</style>
</head>
<body>

<h2>Light-weight Tooltip by FC</h2>

<p>The <span class="tool">WHO<span class="tip">World Health Organization</span></span> was established in 1948.</p>

<p>
    It is part of the
    <span class="tool">UN
        <span class="tip">United Nations, <br>the successor of the <br>League of Nations</span>
    </span>, which was established in 1945.
</p>

<hr>

<p>Explanation and 'minds':</p>

<ul>
    <li>The method consists of local nested spans ('tools' with 'tips' inside), positioned relative-absolute.</li>
    <li>If the same tips are to be used several times throughout the page or website, the tip spans can be populated centrally with Javascript or server-side scripting.</li>
    <li>In the current code the width of the tips is set to <i>auto</i>, and controlled with &lt;br&gt;s in the tip text. Change to fixed width as desired.</li>
    <li>With the current code tablet users must tap (= <i>onclick</i>) rather than press-hold (= <i>onmousedown</i>). It is assumed that that is the intuitive thing most tablet users do, but it can be changed to press-hold.</li>
    <li>The HTML is valid and the code works in IE8 as well.</li>
    <li>For the sake of completeness: IE9 does not form a border-radius when the element has no declared border, or a border-width of 0.</li>
</ul>

<script>
    var tools = document.querySelectorAll('.tool'); // mind the dot
    var nrOfTools = tools.length;
    for (var i = 0; i < nrOfTools; i++) 
        if ('ontouchstart' in window || (window.DocumentTouch && document instanceof DocumentTouch)) 
            tools[i].onclick = function() 
                if (this.children[0].style.visibility == '' || this.children[0].style.visibility == 'hidden')
                    this.children[0].style.visibility = 'visible';
                else
                    this.children[0].style.visibility = 'hidden';
            
         else 
            tools[i].onmouseover = function() 
                this.children[0].style.visibility = 'visible';
            
            tools[i].onmouseout = function() 
                this.children[0].style.visibility = 'hidden';
            
        
    
</script>
</body>
</html>

. 请注意,在双模式机器(触摸屏加键盘)上,似乎无法检测到它处于哪种模式。因此,在这些机器上,其中一种(点击或单击)可能无法在其中一种模式下工作。

发现其他缺陷,或者你有更多关于这些机器的信息吗?请发表评论。

【讨论】:

【参考方案2】:

我找到了解决这个神秘挑战的方法。大多数情况下,您遇到的限制与动态 HTML 有关,并且该函数总是会返回如下内容:

这意味着该对象没有被创建并且 jQuery 无法找到它,那么你需要应用类似这里解释的东西:

https://***.com/a/15090957/2889347

代码必须经过编辑,如下所示:

 $(function () 
        $(document.body).on('mouseenter touchstart mouseleave touchend', '[rel=tooltip]', function () 
            var targets = $('[rel=tooltip]'),
                target = false,
                tooltip = false,
                title = false;

            targets.on('mouseenter touchstart', function () 
                target = $(this);
                tip = target.attr('title');
                tooltip = $('<div id="tooltip"></div>');

                if (!tip || tip == '')
                    return false;

                target.removeAttr('title');
                tooltip.css('opacity', 0)
                    .html(tip)
                    .appendTo('body');

                var init_tooltip = function () 
                    if ($(window).width() < tooltip.outerWidth() * 1.5)
                        tooltip.css('max-width', $(window).width() / 2);
                    else
                        tooltip.css('max-width', 340);

                    var pos_left = target.offset().left + (target.outerWidth() / 2) - (tooltip.outerWidth() / 2),
                        pos_top = target.offset().top - tooltip.outerHeight() - 20;

                    if (pos_left < 0) 
                        pos_left = target.offset().left + target.outerWidth() / 2 - 20;
                        tooltip.addClass('left');
                    
                    else
                        tooltip.removeClass('left');

                    if (pos_left + tooltip.outerWidth() > $(window).width()) 
                        pos_left = target.offset().left - tooltip.outerWidth() + target.outerWidth() / 2 + 20;
                        tooltip.addClass('right');
                    
                    else
                        tooltip.removeClass('right');

                    if (pos_top < 0) 
                        var pos_top = target.offset().top + target.outerHeight();
                        tooltip.addClass('top');
                    
                    else
                        tooltip.removeClass('top');

                    tooltip.css( left: pos_left, top: pos_top )
                        .animate( top: '+=10', opacity: 1 , 50);
                ;

                init_tooltip();
                $(window).resize(init_tooltip);

                var remove_tooltip = function () 
                    tooltip.animate( top: '-=10', opacity: 0 , 50, function () 
                        $(this).remove();
                    );

                    target.attr('title', tip);
                ;

                target.on('mouseleave touchend', remove_tooltip);
                tooltip.on('click', remove_tooltip);
            );
        );
    );

诀窍在于:

$(document.body).on('mouseenter touchstart mouseleave touchend', '[rel=tooltip]', function ()  //... );

这部分代码允许您在代码完全加载到主体上时调用它,它会跟踪您要执行的模式。

此外,这里有一些工具提示在 Android 中按预期工作的屏幕截图。

此外,您还可以添加以下附加事件:

触摸开始 触摸结束

2017 年 7 月 25 日更新:

我在使用某些 WebView 时遇到了一些问题,我将代码升级到以下代码,它应该可以完全正常运行:

$(function() 
    var target = false,
        tooltip = false,
        title   = false;

    $(document.body).on('click tap', function (e) 
        if (event.target.nodeName !== "ABBR" && tooltip != false) 
            remove_tooltip();
        
    );

    var remove_tooltip = function()
    
        tooltip.animate(  top: '-=10', opacity: 0 , 50, function()
        
            $( this ).remove();
        );

        target.attr( 'title', tip );
    ;

    $(document.body).on('click tap', '[rel=tooltip]', function () 
        target  = $( this );
        tip     = target.attr( 'title' );
        tooltip = $( '<div id="tooltip"></div>' );

        if( !tip || tip == '' )
            return false;

        target.removeAttr( 'title' );
        tooltip.css( 'opacity', 0 )
               .html( tip )
               .appendTo( 'body' );

        var init_tooltip = function()
        
            if( $( window ).width() < tooltip.outerWidth() * 1.5 )
                tooltip.css( 'max-width', $( window ).width() / 2 );
            else
                tooltip.css( 'max-width', 340 );

            var pos_left = target.offset().left + ( target.outerWidth() / 2 ) - ( tooltip.outerWidth() / 2 ),
                pos_top  = target.offset().top - tooltip.outerHeight() - 20;

            if( pos_left < 0 )
            
                pos_left = target.offset().left + target.outerWidth() / 2 - 20;
                tooltip.addClass( 'left' );
            
            else
                tooltip.removeClass( 'left' );

            if( pos_left + tooltip.outerWidth() > $( window ).width() )
            
                pos_left = target.offset().left - tooltip.outerWidth() + target.outerWidth() / 2 + 20;
                tooltip.addClass( 'right' );
            
            else
                tooltip.removeClass( 'right' );

            if( pos_top < 0 )
            
                var pos_top  = target.offset().top + target.outerHeight();
                tooltip.addClass( 'top' );
            
            else
                tooltip.removeClass( 'top' );

            tooltip.css(  left: pos_left, top: pos_top  )
                   .animate(  top: '+=10', opacity: 1 , 50 );
        ;

        init_tooltip();
        $( window ).resize( init_tooltip );

        tooltip.bind( 'click tap', remove_tooltip );
    );
);

我做了三个重要的改变:

    我搜索整个网站上的每一次点击/点击,并且仅在选择 ABBR 并定义工具提示时应用已删除的功能。

    $(document.body).on('click tap', function (e) );

    我跟踪了 ABBR 上的点击/点击,并显示了工具提示:

    $(document.body).on('click tap', '[rel=tooltip]', function () );

    我公开了删除功能。另外,我检查了工具提示是否已初始化

你可以问我:你为什么把所有的鼠标事件都换成点击或轻敲?

通常,在移动开发中,您不会跟踪鼠标事件,例如:mouseenter、mouseleave 等。由于人们几乎不会在日常活动中使用鼠标,因此我们更多地使用手指进行点击。

【讨论】:

以上是关于移动友好的工具提示在 Android 浏览器中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Float left 在 ipod、android 智能手机等移动设备中不起作用

scrollTop 在 Android 手机中不起作用

固定位置在移动浏览器中不起作用

navigator.permissions.query 在 android/ios webview 中不起作用

为啥引导工具提示在引导模式中不起作用?

ExtJS3 快速提示在 IE9 中不起作用