【问题标题】:Swap images with animation or delay on JS在 JS 上用动画或延迟交换图像
【发布时间】:2015-12-04 16:14:46
【问题描述】:

我喜欢小提琴:http://jsfiddle.net/17g6q8k0/2/

    <img data-alt-src="http://cdn1.iconfinder.com/data/icons/fatcow/32/accept.png"
src="http://cdn1.iconfinder.com/data/icons/fatcow/32/cancel.png" />

和JS部分

        var sourceSwap = function () {
            var $this = $(this);
            var newSource = $this.data('alt-src');
            $this.data('alt-src', $this.attr('src'));
            $this.attr('src', newSource);
        }

        $(function() {
            $('img[data-alt-src]').each(function() { 
                new Image().src = $(this).data('alt-src'); 
            }).hover(sourceSwap, sourceSwap); 
        });

当您在图像上移动鼠标时,它会发生变化。当您移除鼠标时,它会变回原来的样子。

在当前示例中,它会瞬间改变。

如何添加暂停或动画(动画效果更好)?

这些图片大小相同。但我会将它与不同大小的图像一起使用(如鼠标悬停上的 [f] 和 [facebook] 按钮),并使其更容易眼睛。

【问题讨论】:

    标签: jquery css jquery-animate settimeout


    【解决方案1】:

    我已经稍微更新了你的脚本http://jsfiddle.net/17g6q8k0/182/

    无论如何,您都需要使用 css。第一个选项是创建带有背景的 div 并为其设置动画。

    但是,如果您想使用 ,还有另一种方法。您必须创建包含 2 个图像的容器。

    <div class="hover-image">
      <img src="http://cdn1.iconfinder.com/data/icons/fatcow/32/cancel.png"/>  
      <img class="hover" src="http://cdn1.iconfinder.com/data/icons/fatcow/32/accept.png"/>
    </div>
    

    其中一个必须绝对定位并覆盖第一张图片。

    .hover-image .hover {
      position: absolute;
      left:0;
      top:0;
      opacity: 0;
    }
    

    您可以为这两个图像的不透明度设置动画。

    $this.find("img").each(function(){
      if($(this).hasClass("hover")) {
        $(this).animate({
          'opacity': 1
        }, "slow");
      } else {
        $(this).animate({
          'opacity': 0
        }, "slow")
      }
    });
    

    【讨论】:

    • 太棒了!但是有可能将它们全部放在一条线上吗?所有 3 张图片都在 1 行中,而不是每张都换行?
    • @nikitasius,是的,只需删除 clear:both;来自 CSS 容器 jsfiddle.net/17g6q8k0/210
    • 很好,但是当我添加不同的图像(较小的变化较大)时,它会出现问题:jsfiddle.net/17g6q8k0/212
    • @nikitasius,您可以计算容器宽度jsfiddle.net/17g6q8k0/213 - 请参阅 JS 块中的 cmets
    • 但它们之间有空白空间。这个想法是:使用小图标来节省空间。当使用移动鼠标时,他会看到全文图像。图标在默认状态下应该粘在一起。
    【解决方案2】:

    我知道你想做什么,但不知道。图像替换是 10-15 年前的一种技术。如果要将复选标记设置为取消符号的动画,最好的方法是变形 SVG 对象。有一个完整的库可以为您做到这一点: http://www.transformicons.com/

    他们甚至有一个检查 > 取消标志对象。只有一个对象的代码看起来像这样......

    HTML:

    <button type="button" class="tcon tcon-remove tcon-remove--check" aria-label="remove item">
      <span class="tcon-visuallyhidden">remove item</span>
    </button>
    

    CSS:

    .tcon {
      -webkit-appearance: none;
      -moz-appearance: none;
      appearance: none;
      border: none;
      cursor: pointer;
      display: -webkit-flex;
      display: -ms-flexbox;
      display: flex;
      -webkit-justify-content: center;
      -ms-flex-pack: center;
      justify-content: center;
      -webkit-align-items: center;
      -ms-flex-align: center;
      align-items: center;
      height: 40px;
      transition: 0.3s;
      -webkit-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;
      width: 40px;
      background: transparent;
      outline: none;
      -webkit-tap-highlight-color: transparent;
      -webkit-tap-highlight-color: transparent; }
      .tcon > * {
        display: block; }
      .tcon:hover,
      .tcon:focus {
        outline: none; }
      .tcon::-moz-focus-inner {
        border: 0; }
    
    .tcon-remove {
      height: 40px;
      position: relative;
      -webkit-transform: scale(0.75);
      transform: scale(0.75);
      width: 40px; }
      .tcon-remove::before,
      .tcon-remove::after {
        content: "";
        display: block;
        border-radius: 2px;
        width: 85%;
        height: 25%;
        position: absolute;
        top: 37%;
        left: 8%;
        transition: 0.3s;
        background: black; }
      .tcon-remove::before {
        -webkit-transform: rotate(45deg);
        transform: rotate(45deg); }
      .tcon-remove::after {
        -webkit-transform: rotate(-45deg);
        transform: rotate(-45deg); }
    
    .tcon-remove--check.tcon-transform::before {
      -webkit-transform: rotate(-135deg) translate(5%, -10%);
      transform: rotate(-135deg) translate(5%, -10%);
      top: 50%;
      width: 55%; }
    
    .tcon-remove--check.tcon-transform::after {
      -webkit-transform: rotate(-45deg) translate(20%, 10%);
      transform: rotate(-45deg) translate(20%, 10%);
      top: 50%;
      width: 85%; }
    
    .tcon-visuallyhidden {
      border: 0;
      clip: rect(0 0 0 0);
      height: 1px;
      margin: -1px;
      overflow: hidden;
      padding: 0;
      position: absolute;
      width: 1px; }
      .tcon-visuallyhidden:active,
      .tcon-visuallyhidden:focus {
        clip: auto;
        height: auto;
        margin: 0;
        overflow: visible;
        position: static;
        width: auto; }
    

    JS:

    (function (root, factory) {
      if (typeof define === 'function' && define.amd) {
        // AMD module
        define(factory);
      } else if (typeof exports === 'object') {
        // CommonJS-like environment (i.e. Node)
        module.exports = factory();
      } else {
        // Browser global
        root.transformicons = factory();
      }
    }(this || window, function () {
    
      // ####################
      // MODULE TRANSFORMICON
      // ####################
      'use strict';
    
      var
        tcon = {}, // static class
        _transformClass = 'tcon-transform',
    
        // const
        DEFAULT_EVENTS = {
          transform : ['click'],
          revert : ['click']
        };
    
      // ##############
      // private methods
      // ##############
    
      /**
      * Normalize a selector string, a single DOM element or an array of elements into an array of DOM elements.
      * @private
      *
      * @param {(string|element|array)} elements - Selector, DOM element or Array of DOM elements
      * @returns {array} Array of DOM elements
      */
      var getElementList = function (elements) {
        if (typeof elements === 'string') {
          return Array.prototype.slice.call(document.querySelectorAll(elements));
        } else if (typeof elements === 'undefined' || elements instanceof Array) {
          return elements;
        } else {
          return [elements];
        }
      };
    
      /**
      * Normalize a string with eventnames separated by spaces or an array of eventnames into an array of eventnames.
      * @private
      *
      * @param {(string|array)} elements - String with eventnames separated by spaces or array of eventnames
      * @returns {array} Array of eventnames
      */
      var getEventList = function (events) {
        if (typeof events === 'string') {
          return events.toLowerCase().split(' ');
        } else {
          return events;
        }
      };
    
      /**
      * Attach or remove transformicon events to one or more elements.
      * @private
      *
      * @param {(string|element|array)} elements - Selector, DOM element or Array of DOM elements to be toggled
      * @param {object} [events] - An Object containing one or more special event definitions
      * @param {boolean} [remove=false] - Defines wether the listeners should be added (default) or removed.
      */
      var setListeners = function (elements, events, remove) {
        var
          method = (remove ? 'remove' : 'add') + 'EventListener',
          elementList = getElementList(elements),
          currentElement = elementList.length,
          eventLists = {};
    
        // get events or use defaults
        for (var prop in DEFAULT_EVENTS) {
          eventLists[prop] = (events && events[prop]) ? getEventList(events[prop]) : DEFAULT_EVENTS[prop];
        }
    
        // add or remove all events for all occasions to all elements
        while(currentElement--) {
          for (var occasion in eventLists) {
            var currentEvent = eventLists[occasion].length;
            while(currentEvent--) {
              elementList[currentElement][method](eventLists[occasion][currentEvent], handleEvent);
            }
          }
        }
      };
    
      /**
      * Event handler for transform events.
      * @private
      *
      * @param {object} event - event object
      */
      var handleEvent = function (event) {
        tcon.toggle(event.currentTarget);
      };
    
      // ##############
      // public methods
      // ##############
    
      /**
      * Add transformicon behavior to one or more elements.
      * @public
      *
      * @param {(string|element|array)} elements - Selector, DOM element or Array of DOM elements to be toggled
      * @param {object} [events] - An Object containing one or more special event definitions
      * @param {(string|array)} [events.transform] - One or more events that trigger the transform. Can be an Array or string with events seperated by space.
      * @param {(string|array)} [events.revert] - One or more events that trigger the reversion. Can be an Array or string with events seperated by space.
      * @returns {transformicon} transformicon instance for chaining
      */
      tcon.add = function (elements, events) {
        setListeners(elements, events);
        return tcon;
      };
    
      /**
      * Remove transformicon behavior from one or more elements.
      * @public
      *
      * @param {(string|element|array)} elements - Selector, DOM element or Array of DOM elements to be toggled
      * @param {object} [events] - An Object containing one or more special event definitions
      * @param {(string|array)} [events.transform] - One or more events that trigger the transform. Can be an Array or string with events seperated by space.
      * @param {(string|array)} [events.revert] - One or more events that trigger the reversion. Can be an Array or string with events seperated by space.
      * @returns {transformicon} transformicon instance for chaining
      */
      tcon.remove = function (elements, events) {
        setListeners(elements, events, true);
        return tcon;
      };
    
      /**
      * Put one or more elements in the transformed state.
      * @public
      *
      * @param {(string|element|array)} elements - Selector, DOM element or Array of DOM elements to be transformed
      * @returns {transformicon} transformicon instance for chaining
      */
      tcon.transform = function (elements) {
        getElementList(elements).forEach(function(element) {
          element.classList.add(_transformClass);
        });
        return tcon;
      };
    
      /**
      * Revert one or more elements to the original state.
      * @public
      *
      * @param {(string|element|array)} elements - Selector, DOM element or Array of DOM elements to be reverted
      * @returns {transformicon} transformicon instance for chaining
      */
      tcon.revert = function (elements) {
        getElementList(elements).forEach(function(element) {
          element.classList.remove(_transformClass);
        });
        return tcon;
      };
    
      /**
      * Toggles one or more elements between transformed and original state.
      * @public
      *
      * @param {(string|element|array)} elements - Selector, DOM element or Array of DOM elements to be toggled
      * @returns {transformicon} transformicon instance for chaining
      */
      tcon.toggle = function (elements) {
        getElementList(elements).forEach(function(element) {
          tcon[element.classList.contains(_transformClass) ? 'revert' : 'transform'](element);
        });
        return tcon;
      };
    
      return tcon;
    }));
    

    【讨论】:

    • 我需要为社交按钮制作动画。复选标记只是我在谷歌中喜欢的小提琴的一个例子。用户有小图标(twitter、facebook 等),当他在上面移动鼠标时,他会看到大图标。而且由于尺寸不同,它看起来很疯狂,对眼睛来说太快太锐利了。所以我需要让它慢一点。
    • 你仍然不应该使用图像 + JS。使用图标字体并使用 CSS 控制品牌图标的大小。 Font Awesome 有一个非常容易实现的图标品牌部分:fortawesome.github.io/Font-Awesome/icons/#brand
    • FA 只为 facebook 提供了一个图标“f”。当用户将鼠标移到“f”上时,我需要一个带有“f”的简单解决方案图标和另一个带有“facebook”的图标。
    • 是的,那你是对的——你需要对它进行图像替换。您应该与您的设计负责人交谈,看看他们是否会放弃该要求。最好使用图标字体或上面的 SVG 方法。
    猜你喜欢
    • 2014-07-31
    • 2012-07-19
    • 2014-08-16
    • 2021-08-05
    • 1970-01-01
    • 2016-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多