jquery div hover上的多个文本滚动不起作用

时间:2017-01-19 11:36:23

标签: javascript jquery html css

我有使用jQuery在hover div上滚动文本的此代码:

HTML:

<div id="target" style="width: 300px;height:100px; margin-left: 50px; background-color: #ddd;">

  <span class="tooMuchText tooMuchText1">Got too much text to fit in your content area? Just hover for more more more more more more!</span>
</div>
<br>
<br>
<div id="target" style="width: 300px;height:100px; margin-left: 50px; background-color: #ddd;">

  <span class="tooMuchText tooMuchText1">Got too much text to fit in your content area? Just hover for more more more more more more!</span>
</div>
<br>
<br>
<div id="target" style="width: 300px;height:100px; margin-left: 50px; background-color: #ddd;">

  <span class="tooMuchText tooMuchText1">Got too much text to fit in your content area? Just hover for more more more more more more!</span>
</div>
<br>

JS:

$(function()
  {
   $(".tooMuchText1").hoverForMore({
   "speed": 300,
   "loop": false,
   "target":'#target'
   });
});

CSS:

.tooMuchText {
  overflow: hidden;
  white-space: nowrap;
  display: block;
  text-align: left;
  text-overflow: ellipsis;
  cursor: default;
}

因此,我需要在悬停时使用target ID滚动多个(每个)div文本。但我的代码只能在divtarget ID中使用。我该怎么办这个问题?!

演示jsfiddle

2 个答案:

答案 0 :(得分:2)

这只是一个例子,你可以在div中尝试多个类吗?如果是,我在js小提琴中尝试这个,请检查..如果它可以帮助你

&#13;
&#13;
(function($, window) {
  var isjQuery = !!$.fn.jquery;

  var isFirefox = /Firefox/.test(navigator.userAgent);
  var isMobile = /Mobile/.test(navigator.userAgent);

  var defaults = {
    "speed": 60.0,
    "gap": 20,
    "loop": true,
    "removeTitle": true,
    "snapback": true,
    "alwaysOn": false,
    "addStyles": true,
    "target": true,
    "startEvent": isMobile ? "touchstart" : (isjQuery ? "mouseenter" : "mouseover"),
    "stopEvent": isMobile ? "touchend" : (isjQuery ? "mouseleave" : "mouseout")
  };


  $.fn['hoverForMore'] = function(options) {
    var self = this;
    var head = document.getElementsByTagName('head')[0];
    var originalOverflow, originalOverflowParent, startTime;

    options = $.extend({}, defaults, options);

    var targetSelector = options.target || self.selector;

    // Always-on without looping is just silly
    if (options.alwaysOn) {
      options.loop = true;
      options.startEvent = "startLooping"; // only triggered programmatically
    }

    // Detect CSS prefix and presence of CSS animation
    var hasAnimation = document.body.style.animationName ? true : false,
      animationString = 'animation',
      transitionString = 'transition',
      transformString = 'transform',
      keyframePrefix = '',
      domPrefixes = 'Webkit Moz O ms Khtml'.split(' '),
      pfx = '';

    // Find the CSS prefix, if necessary
    if (hasAnimation === false)
      for (var i = 0; i < domPrefixes.length; i++) {
        if (document.body.style[domPrefixes[i] + 'AnimationName'] === undefined)
          continue;

        pfx = domPrefixes[i];
        animationString = pfx + 'Animation';
        transitionString = pfx + 'Transition';
        transformString = pfx + 'Transform';
        cssPrefix = '-' + pfx.toLowerCase() + '-';
        hasAnimation = true;
        break;
      }

    // Auto-add ellipsis and such
    if (options.addStyles) {
      head.appendChild($(
        '<style type="text/css">' + self.selector + '{' + 'cursor:default;' + 'text-align:left;' + 'display:block;' + 'overflow:hidden;' + 'white-space:nowrap;' + 'text-overflow:ellipsis;' + cssPrefix + 'user-select: none;' + '}</style>')[0]);
    }

    // Non-animation fallback. TODO: Animate with jQuery instead
    if (!hasAnimation) {
      // Fallback to title text hover
      $(options.target || self.selector).each(function(n, el) {
        var $el = $(el);
        $el.attr("title", $.trim($el.text()));
      });
      return self;
    }

    // Keyframes are only used in loop mode
    if (options.loop) {
      // Attach global style
      var $keyframeStyle = $('<style type="text/css"></style>');
      var $keyframeStyleReverse = $('<style type="text/css"></style>');
      head.appendChild($keyframeStyle[0]);
      head.appendChild($keyframeStyleReverse[0]);
    }

    // For non-loop mode, set an empty transform value (FireFox needs this to transition properly)
    else {
      $(self.selector).each(function(n, el) {
        el.style[transformString] = 'translateX(0px)';
      });
    }


    // Attach start event
    $(targetSelector).on(options.startEvent, function(e) {
      startTime = (new Date()).getTime();

      // Get hovered item, and ensure that it contains an overflown item
      var $item = $(options.target ? self.selector : this).filter(":first");
      if (!$item.length) return true;

      var $parent = $item.parent();
      var pixelDiff = $item[0].scrollWidth - $item.width();

      if (pixelDiff <= 0) // && !options.alwaysOn // TODO: <marquee> without overflow
        return true;

      if (options.removeTitle) $item.removeAttr("title");

      // Over-ride the text overflow, and cache the overflow css that we started with
      originalOverflowParent = originalOverflowParent || $parent.css("overflow");
      originalOverflow = originalOverflow || $item.css("overflow");

      $parent.css("overflow", "hidden");
      if (isMobile && options.addStyles)
        $('body').css(cssPrefix + "user-select", "none");

      $item
        .css("overflow", "visible")
        .addClass("scrolling");

      if (options.loop) {
        // Remove a previous clone
        $item.children(".hoverForMoreContent").remove();

        // Attach a duplicate string which will allow content to appear wrapped
        var $contentClone = $('<span class="hoverForMoreContent" />')
          .css({
            "paddingLeft": parseInt(options.gap) + "px"
          })
          .text($item.text());

        $item.append($contentClone);
        var contentWidth = ($contentClone.width() + parseInt(options.gap));

        // Build keyframe string and attach to global style
        var keyframes = '@' + cssPrefix + 'keyframes hoverForMoreSlide { ' + 'from {' + cssPrefix + 'transform:translateX( 0 ) }' + 'to {' + cssPrefix + 'transform:translateX( -' + contentWidth + 'px ) }' + '}';
        $keyframeStyle[0].innerHTML = keyframes;

        // Go go gadget animation!
        var sec = contentWidth / parseFloat(options.speed);

        $item[0].style[animationString] = 'hoverForMoreSlide ' + sec + 's linear infinite';
      } else // if(!options.loop)
      {
        var sec = pixelDiff / parseFloat(options.speed);

        // Apply transition + transform instead of looping
        $item[0].style[transitionString] = cssPrefix + 'transform ' + sec + 's linear';

        // Alas, Firefox won't honor the transition immediately
        if (!isFirefox)
          $item[0].style[transformString] = 'translateX(-' + pixelDiff + 'px)';

        else setTimeout(function() {
          $item[0].style[transformString] = 'translateX(-' + pixelDiff + 'px)';
        }, 0);
      }
    });



    // Attach stop event
    if (!options.alwaysOn)
      $(targetSelector).on(options.stopEvent, function(e) {
        var $item = $(options.target ? self.selector : this).filter(":first");
        if (!$item.length) return true;

        if (options.loop) {
          if (options.snapback) {
            // Reverse our animation
            var contentWidth = $item.children('.hoverForMoreContent').width() + parseInt(options.gap);
            var timeDiff = ((new Date()).getTime() - startTime) * 0.001;
            var offsetX = (timeDiff * options.speed) % contentWidth;
            var switchDirection = offsetX > (contentWidth / 2);

            // Build keyframe string and attach to global style
            var keyframes = '@' + cssPrefix + 'keyframes hoverForMoreSlideReverse { ' + 'from {' + cssPrefix + 'transform:translateX( ' + (0 - offsetX) + 'px ) }' + 'to {' + cssPrefix + 'transform:translateX( ' + (switchDirection ? 0 - contentWidth : 0) + 'px ) }' + '}';
            $keyframeStyleReverse[0].innerHTML = keyframes;

            var sec = (switchDirection ? contentWidth - offsetX : offsetX) * 0.2 / parseFloat(options.speed);
            $item[0].style[animationString] = 'hoverForMoreSlideReverse ' + (sec > 1 ? 1 : sec) + 's linear';

            $item.removeClass("scrolling");

            // After animation resolves, restore original overflow setting, and remove the cloned element
            setTimeout(function() {
              if ($item.is(".scrolling")) return;

              $item
                .children(".hoverForMoreContent")
                .remove();

              $item.css("overflow", originalOverflow);
              $item.parent().css("overflow", originalOverflowParent);

              if (isMobile && options.addStyles)
                $('body').css(cssPrefix + "user-select", 'text');
            }, (sec * 1000) - -50);
          } else // if(!options.snapback)
          {
            $item[0].style[animationString] = '';

            $item
              .css("overflow", originalOverflow)
              .find(".hoverForMoreContent")
              .remove();

            $item.parent().css("overflow", originalOverflowParent);

            if (isMobile && options.addStyles)
              $('body').css(cssPrefix + "user-select", 'text');
          }
        } else // if(!options.loop)
        {
          var timeDiff = ((new Date()).getTime() - startTime) / 1000.0;
          var match = $item[0].style[transitionString].match(/transform (.*)s/);
          var sec = (match && match[1] && parseFloat(match[1]) < timeDiff) ? parseFloat(match[1]) : timeDiff;
          sec *= 0.5;

          if (!options.snapback)
            $item[0].style[transitionString] = '';
          else
            $item[0].style[transitionString] = cssPrefix + 'transform ' + sec + 's linear';

          $item.removeClass("scrolling")

          // Firefox needs a delay for the transition to take effect
          if (!isFirefox)
            $item[0].style[transformString] = 'translateX(0px)';

          else setTimeout(function() {
            $item[0].style[transformString] = 'translateX(0px)';
          }, 0);

          if (!options.snapback) {
            $item.css("overflow", originalOverflow);

            if (isMobile && options.addStyles)
              $('body').css(cssPrefix + "user-select", 'text');
          } else // if(options.snapback)
          {
            setTimeout(function() {
              if ($item.is(".scrolling")) return;
              $item.css("overflow", originalOverflow);

              if (isMobile && options.addStyles)
                $('body').css(cssPrefix + "user-select", 'text');
            }, sec * 1000);
          }
        }

      });


    // To manually refresh active elements when in always-on mode
    self.refresh = function() {
      $(self.selector).each(function(n, el) {
        $(el).not(".scrolling").trigger(options.startEvent);
      })
    };


    // Always-on mode, activate! <marquee>, eat your heart out.
    if (options.alwaysOn)
      self.refresh();

    return self;
  };

})(window.jQuery || $);



$(function() {
  
  $(".tooMuchText1").hoverForMore({
    "speed": 300,
    "loop": false,
    "target": '#target'
  });
  
   $(".tooMuchText2").hoverForMore({
    "speed": 300,
    "loop": false,
    "target": '#target1'
  });
  $(".tooMuchText3").hoverForMore({
    "speed": 300,
    "loop": false,
    "target": '#target2'
  });
});
&#13;
.tooMuchText {
  overflow: hidden;
  white-space: nowrap;
  display: block;
  text-align: left;
  text-overflow: ellipsis;
  cursor: default;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="target" style="width: 300px;height:100px; margin-left: 50px; background-color: #ddd;">

  <span class="tooMuchText tooMuchText1">Got too much text to fit in your content area? Just hover for more more more more more more!</span>
</div>
<br>
<br>
<div id="target1" style="width: 300px;height:100px; margin-left: 50px; background-color: #ddd;">

  <span class="tooMuchText tooMuchText2">Got too much text to fit in your content area? Just hover for more more more more more more!</span>
</div>
<br>
<br>
<div id="target2" style="width: 300px;height:100px; margin-left: 50px; background-color: #ddd;">

  <span class="tooMuchText tooMuchText3">Got too much text to fit in your content area? Just hover for more more more more more more!</span>
</div>
<br>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

这里至少存在一个概念问题:

  • id&#39; s应该始终是唯一的 - 对于相同的项目,请使用类

显然有更优雅的方法可以做到这一点,但是继续使用id,你可以扩展它,并遍历跨度,收集它们的唯一ID,然后获取父级的唯一ID,用它作为目标。

$(function() {
    $(".tooMuchText").each(function() {

    var thisParentId = $(this).parents("div").attr("id");
    var thisId = $(this).attr("id");
    $('#' + thisId).hoverForMore({
      "speed": 300,
      "loop": false,
      "target": '#' + thisParentId
    });

  });
});

要完成此操作,只需为每个SPAN和DIV添加唯一ID即可。

<div id="target3" style="width: 300px;height:100px; margin-left: 50px; background-color: #ddd;">

  <span id='tooMuchText3' class="tooMuchText">Got too much text to fit in your content area? Just hover for more more more more more more!</span>
</div>