【问题标题】:How can you make CSS on-hover content stay in place when you click or stop hovering using Javascript?当您使用 Javascript 单击或停止悬停时,如何使 CSS 悬停内容保持原位?
【发布时间】:2012-11-19 09:37:16
【问题描述】:

我想实现一个身体系统功能。当用户将鼠标悬停在身体​​部位上时,它会突出显示并显示该特定身体部位的信息。我已经按照我想要的方式编写了 CSS,但是 我对 JavaScript 一无所知,以便在单击正文部分或鼠标离开悬停状态时获取信息。 p>

我已经搜索了论坛并发现了类似的问题,并花了几个小时试图从其他人的 javascript 解决方案中弄清楚这一点 - 我正处于需要寻求帮助的地步。

这是我根据自己想要的效果制作的 Flash 原型:

http://inwavemedia.com/temp/proto/Main.html

如果你想看看我现在拥有的内容,这里是实时 HTML:

http://inwavemedia.com/temp/excretory.html

这是我的代码:

<style type="text/css">
#bodysystem-excretory {
 width: 618px;
 height: 504px;
 background: url(excretory.png) no-repeat;
 margin: 10px auto; padding: 0;
 position: relative;
 border: 1px solid #999;
}
#bodysystem-excretory li {
    margin: 0;
    padding: 0;
    list-style: none;
    display: block;
    position: absolute;
}

#bodysystem-excretory a {
    display: block;
/*  text-indent: -9999px;*/
    text-decoration: none;
}

#esoph {
    left: 85px;
    top: 41px;
    width: 46px;
    height: 94px;
    z-index: 10;
}

#lungs {
    left: 76px;
    top: 84px;
    width: 84px;
    height: 68px;
    z-index: 20;
}

#bladder {
    left: 87px;
    top: 148px;
    width: 64px;
    height: 104px;
    z-index: 30;
}

#esoph a {
    height: 94px;
}

#lungs a {
    height: 67px;
}

#bladder a {
    height: 104px;
}


#esoph a:hover {
    background-image: url(excretory.png);
    background-repeat: no-repeat;
    background-position: -25px -561px;
}

#lungs a:hover {
    background-image: url(excretory.png);
    background-repeat: no-repeat;
    background-position: -105px -523px;
}

#bladder a:hover {
    background-image: url(excretory.png);
    background-repeat: no-repeat;
    background-position: -114px -618px;
}

.info span{ 
    display: none

}

.info{
    position:relative;
    z-index:1124;
    color:#000;
}

.info:hover{
    z-index:1125;

}

.info:hover span{
    display:block;
    position:absolute;
    top:-30px;
    left:155px;
    width:370px;
    color:#000;
    background-color:#FFFFFF;
}
</style>

</head>

<body>
<ul id="bodysystem-excretory">
  <li id="esoph">
    <a href="#" class="info"><span id="esoph-info"><h3>Esophagus</h3><p>This is esophagus information. This is esophagus information. This is esophagus information. This is esophagus information. This is esophagus information. This is esophagus information. This is esophagus information. </p></span></a>
  </li>
<li id="lungs"><a href="#" class="info"><span id="lungs-info"><h3>Lungs</h3></span></a></li>
<li id="bladder"><a href="#" class="info"><span id="bladder-info"><h3>Bladder</h3></span></a></li>
</ul>

【问题讨论】:

  • 您的问题是什么?你已经在css中完成了。你想用javascript来做吗?
  • 据我了解@polin,史蒂夫希望这种悬停样式在单击时成为永久样式。查看他的链接,悬停效果很好,就像这个 CSS,但是 clicking 使样式永久化,不像 这个 CSS。
  • 找到解决方案了吗?

标签: javascript css onclick hover mouseevent


【解决方案1】:

以下是您需要做的更改:

<head>
    <title>Untitled Page</title>
    <style type="text/css">
        #bodysystem-excretory
        {
            width: 618px;
            height: 504px;
            background: url(excretory.png) no-repeat;
            margin: 10px auto;
            padding: 0;
            position: relative;
            border: 1px solid #999;
        }
        #bodysystem-excretory li
        {
            margin: 0;
            padding: 0;
            list-style: none;
            display: block;
            position: absolute;
        }

        #bodysystem-excretory a
        {
            display: block; /*  text-indent: -9999px;*/
            text-decoration: none;
        }

        #esoph
        {
            left: 85px;
            top: 41px;
            width: 46px;
            height: 94px;
            z-index: 10;
        }

        #lungs
        {
            left: 76px;
            top: 84px;
            width: 84px;
            height: 68px;
            z-index: 20;
        }

        #bladder
        {
            left: 87px;
            top: 148px;
            width: 64px;
            height: 104px;
            z-index: 30;
        }

        #esoph a
        {
            height: 94px;
        }

        #lungs a
        {
            height: 67px;
        }

        #bladder a
        {
            height: 104px;
        }


        #esoph a:hover
        {
            background-image: url(excretory.png);
            background-repeat: no-repeat;
            background-position: -25px -561px;
        }

        #lungs a:hover
        {
            background-image: url(excretory.png);
            background-repeat: no-repeat;
            background-position: -105px -523px;
        }

        #bladder a:hover
        {
            background-image: url(excretory.png);
            background-repeat: no-repeat;
            background-position: -114px -618px;
        }

        .info span
        {
            display: none;
        }

        .info
        {
            position: relative;
            z-index: 1000;
            color: #000;
        }

        #bodysystem-excretory li[selected='true'] .info
        {
            z-index:1200;
        }

        #bodysystem-excretory li[selected='true'] .info span
        {
            display: block;
            position: absolute;
            top: -30px;
            left: 155px;
            width: 370px;
            color: #000;
            background-color: #FFFFFF;
        }

        .info:hover
        {
            z-index: 1125;
        }

        .info:hover span
        {
            display: block;
            position: absolute;
            top: -30px;
            left: 155px;
            width: 370px;
            color: #000;
            background-color: #FFFFFF;
        }
    </style>
    <script type="text/javascript">
        function SelectOrgan(obj)
        {
            var parentObj = obj.parentNode;
            var organs = document.getElementById("bodysystem-excretory").getElementsByTagName("li");

            for (var i = 0, len = organs.length; i < len; i++)
            {
                organs[i].setAttribute("selected", "false");
            }

            parentObj.setAttribute("selected", "true");
        }
    </script>
</head>
<body>
    <ul id="bodysystem-excretory">
        <li id="esoph" selected="false"><a href="#" class="info" onclick="SelectOrgan(this)"><span id="esoph-info">
            <h3>
                Esophagus</h3>
            <p>
                This is esophagus information. This is esophagus information. This is esophagus
                information. This is esophagus information. This is esophagus information. This
                is esophagus information. This is esophagus information.
            </p>
        </span></a></li>
        <li id="lungs" selected="false"><a href="#" class="info" onclick="SelectOrgan(this)"><span id="lungs-info">
            <h3>
                Lungs</h3>
        </span></a></li>
        <li id="bladder" selected="false"><a href="#" class="info" onclick="SelectOrgan(this)"><span id="bladder-info">
            <h3>
                Bladder</h3>
        </span></a></li>
    </ul>
</body>
</html>

请注意,每个器官都被分配了一个绝对位置,在空间中具有不同的位置。如果您将所有这些都保持相同的左侧、顶部、宽度和高度,那么您将达到您的要求。

【讨论】:

  • 这是一个fiddle 用于此建议。不确定您将所有身体部位分配相同的绝对位置是什么意思 - 当前位置它们出现在正确的位置。
  • 原因是一旦你选择了一个li元素,它的内容就会一直显示出来。现在,当您将鼠标悬停在其他 li 元素上时,它们会显示出来,但在它们后面也会看到所选 li 元素的文本。因此,如果我们分配相同的绝对位置,就可以解决问题。
  • 我看不出如何为它们分配相同的绝对位置来解决重叠文本的问题。
  • span 元素的背景颜色属性将覆盖选定的 li 元素。 span 元素的左、上、右和下位置也应该相同。
  • 为选定的li的span和悬停的span添加高度css也可以解决同样的问题。
【解决方案2】:

我认为前面的任何一个答案都不能完全满足您的要求。这是my suggestion。请注意,CSS 已更改,最后添加了 javascript。

<html>
<head><style type="text/css">
#bodysystem-excretory {
     width: 618px; height: 504px;
     background: url("excretory.png") no-repeat;
     margin: 10px auto; padding: 0;
     position: relative;
     border: 1px solid #999;
}
#bodysystem-excretory li {
    margin: 0; padding: 0;
    list-style: none;
    display: block;
    position: absolute;
}
#bodysystem-excretory a {
    display: block;
    /*  text-indent: -9999px;*/
    text-decoration: none;
}
#esoph {
    left: 85px; top: 41px;
    width: 46px; height: 94px;
    z-index: 10;
}
#lungs {
    left: 76px; top: 84px;
    width: 84px; height: 68px;
    z-index: 20;
}
#bladder {
    left: 87px; top: 148px;
    width: 64px; height: 104px;
    z-index: 30;
}
#esoph a {
    height: 94px;
}
#lungs a {
    height: 67px;
}
#bladder a {
    height: 104px;
}
#esoph:hover, #esoph.selected {
    background-image: url("excretory.png") no-repeat -25px -561px;
}
#lungs:hover, #lungs.selected {
    background-image: url("excretory.png") no-repeat -105px -523px;
}
#bladder:hover, #bladder.selected {
    background-image: url("excretory.png") no-repeat -114px -618px;
}
.info span{ 
    display: none
}
.info{
    position:relative;
    z-index:1124;
    color:#000;
}
.selected .info{
    z-index:1125;
}
.selected .info span {
    display:block; position:absolute;
    top:-30px; left:155px;
    width:370px;
    color:#000; background-color:#FFFFFF;
}​</style></head>
<body>
<ul id="bodysystem-excretory">
<li id="esoph">
<a href="#" class="info">
<span id="esoph-info"><h3>Esophagus</h3>
<p>
This is esophagus information. This is esophagus information. 
This is esophagus information. This is esophagus information.
This is esophagus information. This is esophagus information.
This is esophagus information. </p></span></a>
</li>
<li id="lungs"><a href="#" class="info">
<span id="lungs-info"><h3>Lungs</h3></span></a>        
</li>
<li id="bladder"><a href="#" class="info">
<span id="bladder-info"><h3>Bladder</h3>
</span></a></li>
</ul>​<script type="text/javascript">
// Get the <li> elements as a list called 'parts'
var parts = 
    document.getElementById('bodysystem-excretory').getElementsByTagName('li');
function getClickFunction(part) {
    return function() {
// This is the function that will be called when one of the <li>s is clicked
        if (part.className == 'selected') {    // if the body part is already selected
            part.className = '';               // ... then deselect it
        }
        else {                                 // otherwise,
            // first deselect all of the body parts
            for (var i = 0; i < parts.length; i++) {
                parts[i].className = '';
            }
            // then select the one that's been clicked
            part.className = 'selected';
        }
    }
}
// Now, attach this function to all of the <li> elements representing body parts      
for (var i = 0; i < parts.length; i++) {
    parts[i].onclick = getClickFunction(parts[i]);
}​
</script></body></html>

【讨论】:

    【解决方案3】:

    您可以添加一个点击事件,查看我们点击的内容,然后在点击时永久更改样式。然后,这将永久“显示”新部分。

    您的 HTML:

    <li id="lungs" onclick="highlight(this.id)">
       <!--some stuff-->
    </li>
    

    在 javascript 中(为简单起见,我将其放入 &lt;script&gt; 标记中,只需将此 + 您的其他案例添加到您的标题中):

     <script> 
       function highlight(id) {
           var part = document.getElementById(id);
           switch(id){
              case "lungs":
                 part.style.backgroundImage="url(excretory.png)";
                 part.style.backgroundRepeat="no-repeat";
                 part.style.backgroundPosition="-105px 523px";
                 break;
              //rinse repeat for all cases, don't forget the : after your case and to add break; at the end of each line
              default:
                 //do nothing, or something, whatever
        }
     </script>
    

    您可以了解更多关于javascript switch 语句here

    【讨论】:

      【解决方案4】:

      我认为最优雅的方式是为每个器官设置两个背景图像,[organ].png[organ]_hover.png。然后通过对所有器官应用相同的类为所有器官创建一个悬停事件(如.organ);

      此时你可以使用jQuery的.css()函数来改变特定器官的背景(使用$(this).attr("id")获取后),添加_hover后缀。

      您还应该保留当前器官的记录,因此每当用户将鼠标悬停在新器官上时,您将先前器官的背景更改回[organ].png,然后将新器官保存为当前器官。

      至于信息,就用你已经提取的器官名称来做display:block;,和之前的display:none;

      编辑:这是一个 fiddle 演示核心​​功能

      HTML:

         <div id="human_body">
                  <div class="organ" id="lungs"></div>
                  <div class="organ" id="liver"></div>
                  <div class="organ" id="pancreas"></div>
                  <div class="organ" id="heart"></div>
                  <div class="organ" id="kidneys"></div>
              </div>        
              <div id="info">
                  <div id="lungs_info">
                      Lungs
                  </div>
                  <div id="pancreas_info">
                      Pancreas
                  </div>
                  <div id="liver_info">
                      Liver
                  </div>
                  <div id="heart_info">
                      Heart
                  </div>
                  <div id="kidneys_info">
                      Kidneys
                  </div>
              </div>
      

      CSS:

      .organ {
      width:40px;
          height:40px;
          margin:10px;
      }
      
      #lungs {
              background:url("http://www.fishweb.co.il/organs/lungs.png");
          }
          #heart {
              background:url("http://www.fishweb.co.il/organs/heart.png");
          }
          #pancreas {
              background:url("http://www.fishweb.co.il/organs/pancreas.png");
          }
          #kidneys {
              background:url("http://www.fishweb.co.il/organs/kidneys.png");
          }
          #liver {
              background:url("http://www.fishweb.co.il/organs/liver.png");
      }
      
      #info>div {
      display:none;
      }
      

      ​ ​JS(JQuery):

      var current='';
      $(".organ").mouseover(
       function(){
           if (current!='') {
               $("#" + current).css("background","url(http://www.fishweb.co.il/organs/" + current +".png)"); // remove the highlight from the prev organ
               $("#" + current + "_info").hide();
           }
           current = $(this).attr("id");
           $(this).css("background","url(http://www.fishweb.co.il/organs/" + current +"_hover.png)"); // highlight the current organ
           $("#" + current + "_info").show();
       }
          );​
      

      【讨论】:

      • 我有点困惑为什么你需要获取 id。
      • 您需要 ID 以确定悬停的器官(您不能只使用上下文 this 关键字,因为每个器官都有自己的悬停图像)。我在答案中添加了一个小提琴来演示核心功能。
      • 谢谢,我明白了……所以它实际上是用于“信息”文本而不是更改背景图像。
      • 没有。它也适用于背景图像。看看小提琴。
      • 谢谢,现在我确实明白了。出于几个(不是非常重要但有时很重要)原因,我不会这样做 - (i)需要在 javascript 和 css 中包含图像 url,这可能会变得混乱和(ii)鼠标悬停最初会导致图像在加载“..._hover.png”图像时消失。
      【解决方案5】:

      您需要在相互对应的链接和容器上创建一组简单的标识符。

      JSFiddle: http://jsfiddle.net/Y4Wtn

      <style>
          .btn {font-weight:normal}
          .btn.active {font-weight:bold;}
          .pane {display:none;border:1px #ccc solid;padding:10px;}
          .pane.active {display:block;}
      </style>
      <script>
      // insert jquery here
      $(document).read(function(){
      
          $('.btn').click(function(){
              // grab the rel value of the the link that was clicked
              var thisRel = $(this).attr('rel');
              // remove active class from all .btn
              $('.btn').removeClass('active');
              // add active class to link that was clicked
              $(this).addClass('active');
              // remove all active classes from .pane
              $('.pane').removeClass('active');
              // add class active to pane with the same rel value clicked link
              $('.pane[rel="'+thisRel+'"]').addClass('active');         
          });
      
      });
      </script>
      <ul>
          <li><a href="#1" class="btn active" rel="1">Item One</a></li>
          <li><a href="#2" class="btn" rel="2">Item Two</a></li>
          <li><a href="#3" class="btn" rel="3">Item Three</a></li>
      </ul>
      
      <div class="pane active" rel="1">Pane One</div>
      <div class="pane" rel="2">Pane Two</div>
      <div class="pane" rel="3">Pane Three</div>
      

      【讨论】:

      • 对于 OP(他对 Javascript 一无所知),可能应该提到它使用 library called jQuery
      • 感谢@Stuart 指出这一点。我喜欢这是我的第一条评论。让我们希望,为了您和我,读者至少知道这么多或重点是什么。
      • 哈,好吧,我认为你不能认为这是理所当然的。大多数初学者的 Javascript 资源都没有提到 jQuery。
      猜你喜欢
      • 2016-10-27
      • 1970-01-01
      • 1970-01-01
      • 2013-07-23
      • 2013-11-26
      • 1970-01-01
      • 2013-03-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多