【问题标题】:jQuery variable globally defined but logging as undefinedjQuery变量全局定义但记录为未定义
【发布时间】:2015-05-11 19:31:17
【问题描述】:

我正在制作一个类似于亚马逊等网站上的产品图片查看器(您将鼠标悬停在图片上,它会显得更大——点击图片缩略图,它会将主图片设置为点击的图片)。

除了背景信息,我在控制主图像的函数之外设置了两个全局变量。一些奇怪的事情发生了,变量只定义到代码执行的某个点,然后它们变成“未定义”。

这是我的标记:

<div id="product-image-gallery">
   <div id="product-image-holder" style="background-image: url('http://example.com/images/main-image.jpg');">My Main Image
   </div>

   <ul>
     <li class="product-thumb">
       <img src="http://example.com/images/image-1.jpg"/>
     </li>
     <li class="product-thumb">
       <img src="http://example.com/images/image-2.jpg"/>
     </li>
   </ul>
</div>

在 jQuery 中,我将原始图像和图像背景路径存储在两个全局变量中,然后定义更改主图像容器以显示正确图像的函数。这是我的 jQuery:

var $originalImage = $('#product-image-holder');
var $originalImageSrc = $originalImage.css('background-image');

$('#product-image-gallery ul li.product-thumb').click(function () {
    $('li.product-thumb.active').removeClass('active');
    $(this).addClass('active');
});

$('#product-image-gallery ul li.product-thumb').hover(
//mouseenter event
    function () {
        var $imageChange = $(this).find('img');
        var $imageChangeSrc = 'url(\'' + $imageChange.attr('src') + '\')';
        $originalImage.css("background-image", $imageChangeSrc);
},
//mouseleave event
function () {
    var $activeImage = $('#product-image-gallery ul li.product-thumb.active img');
    var $activeImageSrc = 'url(\'' + $activeImage.attr('src') + '\')';

    if($(this).hasClass('active')){
        return;
    }
    else if ($activeImage != '') {
        $originalImage.css("background-image", $activeImageSrc);
    }
    else {
        $originalImage.css("background-image", $originalImageSrc);
    }
});

当我查看页面时,鼠标悬停时一切正常,除了原始图像路径将自身重置为未定义(我可以在控制台中看到这种行为)。我完全不知道是什么导致了这种情况的发生。

非常感谢任何关于什么会使这个变量本身未设置的建议。

[编辑] 这是我的示例的 jsfiddle,显示完全相同的行为: https://jsfiddle.net/htxxnfuy/

【问题讨论】:

  • 您的代码总是通过else 条件,而不是ifelse if
  • 如果忽略if 条件,它真的有效吗? jsfiddle.net/htxxnfuy/3
  • 附带说明,您正在使用Javascript 操作变量。没有 jQuery 变量这样的东西。

标签: jquery html image


【解决方案1】:

您正在根据空字符串检查可能的元素集合。当试图找出 jQuery 选择器是否返回任何项目(或许多)时,您可以测试它的 length 属性。

我还稍微减少了你的代码:

$(function () {
    // To make your code a bit easier to understand, use $ to prefix
    // only variables that represent a jQuery selector.
    var $originalImage = $('#product-image-holder');
    var originalImageSrc = $originalImage.css('background-image');
    var containerSelector = '#product-image-gallery ul li.product-thumb';
    var $container = $(containerSelector);

    // You can attach as many event handlers as you need in just
    // one go. Also, it's better to use mouseenter and mouseleave
    // instead of hover.
    $container.on({ click: function () {
            $('li.product-thumb.active').removeClass('active');

            $(this).addClass('active');
    }, mouseenter: function () {
        var $imageChange = $(this).find('img');
        var imageChangeSrc = 'url(\'' + $imageChange.attr('src') + '\')';

        $originalImage.css('background-image', imageChangeSrc);
    }, mouseleave: function () {
        var $activeImage = $(containerSelector + '.active img');
        var activeImageSrc = 'url(\'' + $activeImage.attr('src') + '\')';

        // I would review the necessity of this entire check.
        if ($(this).hasClass('active')) {            
        } else if ($activeImage.length > 0) { 
            // If there's at least one element coming
            // from the selector above.           
            $originalImage.css('background-image', activeImageSrc);
        } else {           
            $originalImage.css('background-image', originalImageSrc); 
        }
    }});
});

Demo

【讨论】:

  • 感谢这段代码中超级有用的 cmets。我显然是 Javascript 和 jQuery 的新手,您的回答有助于说明最佳实践和代码清洁度。干杯!
  • 没问题。我很高兴能帮上忙。
【解决方案2】:

您检查.active 图像是否找到不正确。如果没有匹配选择器,则结果是长度为 0 的元素的集合。

if ($activeImage.length) { // <-- this line
    $originalImage.css("background-image", $activeImageSrc);
}

var $originalImage = $('#product-image-holder');
var $originalImageSrc = $originalImage.css('background-image');

$('#product-image-gallery ul li.product-thumb').click(function () {
    $('li.product-thumb.active').removeClass('active');
    $(this).addClass('active');
});

$('.product-thumb').hover(
//mouseenter event
function () {
    var $imageChange = $(this).find('img');
    var $imageChangeSrc = 'url(\'' + $imageChange.attr('src') + '\')';
    $originalImage.css("background-image", $imageChangeSrc);
},
//mouseleave event
function () {
    var $activeImage = $('li.active img');
    var $activeImageSrc = 'url(\'' + $activeImage.attr('src') + '\')';

    if($(this).hasClass('active')){
        return;
    }
    else if ($activeImage.length) { // <-- this line
        $originalImage.css("background-image", $activeImageSrc);
    }
    else {
        $originalImage.css("background-image", $originalImageSrc);
    }
});
#product-image-holder {
  height: 50px;
  width: 50px;
}
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<div id="product-image-gallery">
   <div id="product-image-holder"
        style="background-image: url('http://placehold.it/50x50');">
     My Main Image
   </div>

   <ul>
     <li class="product-thumb">
       <img src="http://placehold.it/52x52"/>
     </li>
     <li class="product-thumb">
       <img src="http://placehold.it/51x51g"/>
     </li>
   </ul>
</div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-12
    • 2019-04-08
    • 2018-09-17
    • 1970-01-01
    • 1970-01-01
    • 2022-11-22
    • 1970-01-01
    相关资源
    最近更新 更多