草庐IT

javascript - 如果发生更改,我该如何中断 eventListener?

coder 2025-02-27 原文

我已经创建了自己的小图像 slider ,为了让加载器正常工作,我必须创建一个 addEventListener,然后将加载的图像附加到 DOM 中。

但是,在这种情况下存在一个错误:当图像需要一段时间才能加载并且用户在加载之前点击它以查看下一张图像时,事件监听器仍在工作背景,当图像完全加载时,它会覆盖用户当前正在查看的内容。

我的 HTML:

<template name="ImageGallery">
    {{#each galleryImages}}
        {{#if viewingImage}}
            {{> Image}}
        {{/if}}
    {{/each}}
</template>

<template name="Image">
    <div class="image-in-gallery">LOADING</div>
</template>

检查用户想要看到的“图像”是否是我们在each 迭代中点击的图像(从而显示它):

Template.ImageGallery.helpers({
    viewingImage: function() {
        var self = this
        var galleryImages = Template.parentData().galleryImages
        var renderImage = false
        var viewing = Template.instance().viewingImage.get()
        var posOfThisImage = lodash.indexOf(galleryImages, self)
        if (viewing === posOfThisImage) {
            renderImage = true
        }
        return renderImage
    }
})

使用户能够看到下一个“图像”并在我们到达结尾时循环:

Template.ImageGallery.events({
    'click .click-to-see-next-image': function(event, template) {
        var viewing = template.viewingImage.get()
        var imageCount = this.galleryImages.length
        var nextImage = ++viewing
        if (nextImage < imageCount) {
            template.viewingImage.set(nextImage)
        }
        else {
            template.viewingImage.set(0)
        }
    }
})

加载程序:

Template.Image.onRendered({
    var imageUrl = Template.currentData().name + Template.parentData().name + '.jpg'
    var imageObj = new Image()
    imageObj.src = imageUrl

    imageObj.addEventListener('load', function() {
        $('.image-in-gallery').empty()
        $('.image-in-gallery').append($(imageObj))
    }
})

您可以看到问题出在哪里:empty()append() 当然会覆盖用户当前查看的图像并将其设置为任何内容下一个加载。

我想以某种方式在 addEventListener 函数中添加一个 break 以查看加载的图像是否实际上是用户想要看到的图像。但是有两个问题:

1) ReactiveVar 变量在此模板中不可用。毕竟我需要使用 Session 变量吗?

2) 我不知道如何破解。

有人能帮忙吗?

最佳答案

通读你的问题让我想到,也许可以重建你的模板设置而不需要模板中的这些复杂代码并修复根本原因 - 无法理解当前可见的图像并轻松设置下一个可见。

我发现最好的办法是忘记尝试从子模板访问父数据上下文,因为 ReactiveVar 无论如何都无法通过数据上下文访问(您肯定已经发现)。并且数据上下文层次结构依赖于 Blaze html,因此不建议以这种方式使用它们。

另一个极端是有 Session 变量,那将是非常全局的。

幸运的是,有一条中间道路。

在 Template 命名空间之外定义 ReactiveVar ,然后父模板和子模板都可以平等地访问它。如果您正在尝试编写一个包,并且不想污染全局 Session 命名空间,这尤其有效。

例如把这个放在 hello.html 中:

<head>
  <title>rangetest</title>
</head>

<body>
  <h1>Welcome to RangeTest!</h1>

  {{> hello}}
  {{> rangeList}}
</body>

<template name="hello">

  <p>And another test {{anotherTest}}</p>
</template>

<template name="rangeList">
  {{#each ranges}}
    {{> range}}
  {{/each}}
</template>


<template name="range">
  <p>{{name}}</p>  
  <input type="range" value="{{value}}" min="1" max="10">
</template>

这在 hello.js 中

if (Meteor.isClient) {
  anotherDict = new ReactiveDict('another');

  anotherDict.set('hey',2);

  Template.hello.helpers({  
    anotherTest: function() {
      return anotherDict.get('hey');
    }
  });

  Template.rangeList.helpers({
    ranges: function() {
      var ranges = [
        {
          'name':'first',
          'value': 5
        },
        {
          'name':'second',
          'value': 6
        },
        {
          'name':'third',
          'value': 7
        },
        {
          'name':'fourth',
          'value': 8
        }
      ];
      return ranges;
    },
  });

  Template.range.events({
   'input input[type="range"]': function(e,t) {  
    var value = parseInt(e.target.value);    
    anotherDict.set('hey',value);    
   }
  });
}    

您会看到 react 变量在模板之间很好地传播。

这可能无法回答您关于事件监听器的问题,但希望您能够在实现 react 性之后用 Template.Image.events({ 事件监听器替换您手动添加的事件监听器我已经提议,那些将被紧紧地绑定(bind)到特定的子模板,并且它们将不会不可预测地触发。

附注我有使用 ReactiveDict 和范围输入的示例,因为这是我需要解决类似问题的用例。我对所有三个选项都进行了调查,这是一个最终奏效的选项,并且感觉或多或少也是 meteor 般的方式。

关于javascript - 如果发生更改,我该如何中断 eventListener?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34353408/

有关javascript - 如果发生更改,我该如何中断 eventListener?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby-on-rails - Ruby on Rails 迁移,将表更改为 MyISAM - 2

    如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设

  4. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  5. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  6. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  7. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  8. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  9. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  10. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

随机推荐