【问题标题】:tooltip in pure JS纯 JS 中的工具提示
【发布时间】:2012-12-04 20:18:37
【问题描述】:

我正在尝试此代码,但我得到:document.getElementsByName(...).style is undefined

我认为代表团也有问题。有什么帮助吗?

<html>
    <head>
    <style type="text/css">
    #toolTip {
        position:relative;
        width:200px;
        margin-top:-90px;
    }

    #toolTip p {

        padding:10px;
        background-color:#f9f9f9;
        border:solid 1px #a0c7ff;
        -moz-border-radius:5px;-ie-border-radius:5px;-webkit-border-radius:5px;-o-border-radius:5px;border-radius:5px;
    }

    #tailShadow {
        position:absolute;
        bottom:-8px;
        left:28px;
        width:0;height:0;
        border:solid 2px #fff;
        box-shadow:0 0 10px 1px #555;
    }

    #tail1 {
        position:absolute;
        bottom:-20px;
        left:20px;
        width:0;height:0;
        border-color:#a0c7ff transparent transparent transparent;
        border-width:10px;
        border-style:solid;
    }

    #tail2 {
        position:absolute;
        bottom:-18px;
        left:20px;
        width:0;height:0;
        border-color:#f9f9f9 transparent transparent transparent;
        border-width:10px;
        border-style:solid;
    }
    </style>
    <script type='text/javascript'>
    function load () {
            var elements = document.getElementsByName('toolTip');
            for(var i=0; i<elements.length; i++) {
                document.getElementsByName(elements[i]).style.visibility = 'hidden';
            }
        }
    </script>

    </head>



    <body onload="load()">
    <br><br><br><br><br><br><br><br><br><br><br><br>
    <a class="hd" 
    onMouseOver="document.getElementsByName('toolTip')[0].style.visibility = 'visible'"
    onmouseout ="document.getElementsByName('toolTip')[0].style.visibility = 'hidden'">aqui</a>
    <div id="toolTip" name="toolTip">
        <p>i can haz css tooltip</p>
        <div id="tailShadow"></div>
        <div id="tail1"></div>
        <div id="tail2"></div>
    </div>

    <br><br><br>
    <a class="hd" 
    onMouseOver="document.getElementsByName('toolTip')[0].style.visibility = 'visible'"
    onmouseout ="document.getElementsByName('toolTip')[0].style.visibility = 'hidden'">aqui</a>
    <div id="toolTip" name="toolTip">
        <p>i can haz css tooltip</p>
        <div id="tailShadow"></div>
        <div id="tail1"></div>
        <div id="tail2"></div>
    </div>

    </body>
    </html>

demo

【问题讨论】:

  • 你有重复的 id,这是不可能的(根据定义,ID 是唯一的)

标签: javascript tooltip


【解决方案1】:

尝试将 id toolTip 更改为类:

<div class="toolTip">...</div>

并更改您的 JS 以使用 display 样式,而不是可见性,并且最好使用 JS 事件委托来处理 onmouseover:

function load()
{
    var i, tooltips = document.getElementsByClassName('toolTip'),
    mouseOver = function(e)
    {//handler for mouseover
        e = e || window.event;
        var i, target = e.target || e.srcElement,
        targetToolTip = target.nextElementSibling || nextSibling;//gets the next element in DOM (ie the tooltip)
        //check if mouse is over a relevant element:
        if (target.tagName.toLowerCase() !== 'a' || !target.className.match(/\bhd\b/))
        {//nope? stop here, then
            return e;
        }
        targetToolTip.style.display = 'block';//make visible
        for (i=0;i<tooltips.length;i++)
        {//closures are neat --> you have a reference to all tooltip elements from load scope
            if (tooltips[i] !== targetToolTip)
            {//not the one you need to see
                tooltips[i].style.display = 'none';
            }
        }
    };
    for (i=0;i<tooltips.length;i++)
    {
        tooltips[i].style.display = 'none';
    }
    //add listener:
    if (document.body.addEventListener)
    {//IE > 9, chrome, safari, FF...
        document.body.addEventListener('mouseover',mouseOver,false);
    }
    else
    {//IE8
        document.body.attachEvent('onmouseover',mouseOver);
    }
}

如果这段代码不清楚,Google JavaScript 事件委托和闭包,但这正是我处理这类事情的方式。 IMO,它相当有效(您可以使用闭包范围来跟踪当前可见的工具提示,而不是遍历所有工具提示,这会更好:

function load()
{
    var i, tooltips = document.getElementsByClassName('toolTip'),
    currentToolTip,//<-- reference currently visible
    mouseOver = function(e)
    {
        e = e || window.event;
        var i, target = e.target || e.srcElement,
        targetToolTip = target.nextElementSibling || nextSibling;

        if (target.tagName.toLowerCase() !== 'a' || !target.className.match(/\bhd\b/) || targetToolTip === currentToolTip)
        {//add check for currently visible TT, if so, no further action required
            return e;
        }
        if (currentToolTip !== undefined)
        {
            currentToolTip.style.display = 'none';//hide currently visible
        }
        targetToolTip.style.display = 'block';//make new visible
        currentToolTip = targetToolTip;//keep reference for next event
    };
    for (i=0;i<tooltips.length;i++)
    {
        tooltips[i].style.display = 'none';
    }
    if (document.body.addEventListener)
    {
        document.body.addEventListener('mouseover',mouseOver,false);
    }
    else
    {
        document.body.attachEvent('onmouseover',mouseOver);
    }
}

你就在那里。

编辑:
要在鼠标移出时隐藏工具提示,您可以直接添加第二个侦听器:

function load()
{
    var i, tooltips = document.getElementsByClassName('toolTip'),
    currentToolTip,//<-- reference currently visible
    mouseOver = function(e)
    {
        e = e || window.event;
        var i, target = e.target || e.srcElement,
        targetToolTip = target.nextElementSibling || nextSibling;

        if (target.tagName.toLowerCase() !== 'a' || !target.className.match(/\bhd\b/) || targetToolTip === currentToolTip)
        {//add check for currently visible TT, if so, no further action required
            return e;
        }
        if (currentToolTip !== undefined)
        {
            currentToolTip.style.display = 'none';//hide currently visible
        }
        targetToolTip.style.display = 'block';//make new visible
        currentToolTip = targetToolTip;//keep reference for next event
    },
    mouseOut = function(e)
    {
        e = e || window.event;
        var movedTo = document.elementFromPoint(e.clientX,e.clientY);//check where the cursor is NOW
        if (movedTo === curentToolTip || currentToolTip === undefined)
        {//if cursor moved to tooltip, don't hide it, if nothing is visible, stop
            return e;
        }
        currentTooltip.style.display = 'none';
        currentTooltip = undefined;//no currentToolTip anymore
    };
    for (i=0;i<tooltips.length;i++)
    {
        tooltips[i].style.display = 'none';
    }
    if (document.body.addEventListener)
    {
        document.body.addEventListener('mouseover',mouseOver,false);
        document.body.addEventListener('mouseout',mouseOut,false);
    }
    else
    {
        document.body.attachEvent('onmouseover',mouseOver);
        document.body.attachEvent('onmouseout',mouseOut);
    }
}

注意,这是完全未经测试的。我不完全确定 IE elementFromPoint(获取在特定坐标处呈现的 DOM 元素),或者即使 IE 事件对象具有 clientXclientY 属性,但我想快速google 会告诉你更多,包括如何在旧的、肮脏的、可怕的 IE8 中获取坐标和光标下的元素,但这应该帮助你。当然,如果你不希望tooltip的内容是可选择的,只要把mouseOut函数改成:

mouseOut = function(e)
{
    e = e || window.event;
    var target = e.target || e.srcElement;
    if (currentToolTip)
    {
        currentToolTip.style.diplay = 'none';
        currentToolTip = undefined;
    }
};

无需检查鼠标移出是否在正确的元素上,只需检查是否有当前工具提示,然后将其隐藏。

【讨论】:

  • jsbin.com/imosiz/3/edit 只是有问题。工具提示是持久的。谢谢!
  • 哦,在这种情况下,为onmouseout 事件添加第二个侦听器就可以了,我将添加一些建议
  • @anvd: 好了,我添加了 2 个建议:一个是not 如果光标在其上,则隐藏工具提示,另一个是隐藏工具提示,只要鼠标离开锚点(好吧,客户端移出哪个元素并不重要,如果工具提示可见,它将始终是类 hd 的锚点)
【解决方案2】:

尝试使用类来标记工具提示:

<div id="toolTip1" class="toolTip">
    <p>i can haz css tooltip</p>
    <div id="tailShadow"></div>
    <div id="tail1"></div>
    <div id="tail2"></div>
</div>

和 JQuery 使用类作为选择器来切换可见性:

$('.toolTip').attr('visibility', 'hidden')

一定要清理非唯一的 ID - 否则这会给你带来无穷无尽的麻烦

【讨论】:

  • 这里的 jQuery 标签在哪里?请不要假设全世界都在使用 jQuery。有些人只是点赞以了解更多关于 JS 的工作方式
  • 好吧,我同意你关于缺少标签的观点,但同时 OP 并没有明确表示他们想要一个非 jQuery 答案(毕竟 jQuery 仍然是 JavaScript 下的引擎盖:) )。 jQuery 解决方案仍然是一个可行的选择,在我看来是一个更优雅的解决方案(当然,前提是 OP 没有排除 jQuery 的特殊要求)——我猜由 OP 来决定。
  • 确定 OP 指定他不想要 jQ 答案:问题的标题(“纯 JS 中的工具提示”)对此非常清楚。如果标题有任何不同,那么您绝对正确地说 jQ 是一个有效的答案......顺便说一句:当然 jQ 是 JS 在引擎盖下,但我只是那些无法忍受不知道什么的人之一发生在引擎盖下:)。
【解决方案3】:

您的问题很可能是因为您对两个工具提示使用了相同的id。这是无效的; id 应该是唯一的——给定页面中只有一个元素应该有一个特定的 ID。

如果您需要多个对象的共享标识符,请改用class

【讨论】:

    猜你喜欢
    • 2013-08-23
    • 2020-11-21
    • 2016-07-09
    • 2012-11-11
    • 1970-01-01
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    • 2022-08-14
    相关资源
    最近更新 更多