jQuery 事件停止使用 RxJS

jQuery events stop working with RxJS

本文关键字:RxJS 事件 jQuery      更新时间:2023-09-26

所以,基本上,我的问题是在我的程序开始时,jQuery .css()工作得很好,经过以下测试:

$("#canvas").css("border", "3px solid red");

在那之后,当我尝试添加一个div时 - 确实在需要时添加它 - .css()停止对该元素工作。喜欢这个:

var elem = $("<div/>", {"class": "circle"});
elem.css({'background-color': color})
    .appendTo($("#circles"));

这只是附加了一个<div class="circle"></div>,没有样式,以后不能.remove() 'd-

小提琴:http://jsfiddle.net/bh79fe87/

完整的代码如下所示(LiveScript):

O = Rx.Observable
## Extensions
Rx.Observable.repeatFunc = -> Rx.Observable.return null .map it .repeat!
Rx.Observable.prototype.scanCount = -> this.map 1 .scan 0 (+) .startWith 0
## Utils
write = (t, s) --> t.html t.html! + s + '<br />'
pairs-to-obj = -> {[p[0], p[1]] for p in it}
assoc = (m, t) -->
  for k, v of m
    if k of t then [k, t[k]]
              else [k, v]
  |> (++ [[k, v] for k, v of t if k not of m])
  |> pairs-to-obj
toLocal = (e, x, y) ->
  o = $(e).offset!
  {x: x - o.left, y: y - o.top}
## Game
createCircle = ->
  x = Math.random! * ($(canvas).width() - 20)
  y = -40 + Math.random! * 10
  color = ['#FF0000', '#00FF00', '#0000FF'][Math.floor Math.random! * 3]
  do
    x: x
    y: y
    color: color
createCircleStream = ($canvas, $circles) ->
  elem = $ '<div/>', class: 'circle'
  elemclicks = O.fromEvent elem, 'click'
    .map -> true
    .first!      # Kill the event after a click.
  stream = O.interval 16
    .scan createCircle!, (obj, click) -> assoc obj, y: obj.y + 1
    .takeWhile -> it.y < $canvas.height! + 1
  killstream = stream
    .filter -> it.y > $canvas.height!
    .merge elemclicks
    .map -> true
    .first!
  do
    clicks: elemclicks
    stream: stream
    kill: killstream
    elem: elem
$ ->
  $canvas = $ '#canvas'
  $hits = $ '#hits'
  $missclicks = $ '#missclicks'
  $misses = $ '#misses'
  $circles = $ '#circles'
  $canvas.css 'border', '3px solid red'
  # Events
  canvasclicks = O.fromEvent $canvas, 'click'
    .map -> toLocal canvas, it.pageX, it.pageY
  # Data streams
  circlestream = O.return 1 # O.repeatFunc -> createCircleStream $canvas, $circles
    .repeat!
    .controlled!
  circles = circlestream.map -> createCircleStream $canvas, $circles
  circleclicks = circles
    .flatMap (circle) ->
      circle.clicks
        .map -> circle
  circleupdates = circles
    .flatMap (circle) ->
      circle.stream
        .map -> assoc it, elem: circle.elem
        .takeUntil circle.kill
  circlekills = circles
    .flatMap (circle) ->
      circle.kill
        .map -> circle.elem
  hits = circleclicks.scanCount!
  missclicks = canvasclicks.scanCount!.combineLatest hits, (-)
  misses = circlekills.scanCount!.combineLatest hits, (-)
  # Side effects
  circles.subscribe ->
    it.elem.css 'background-color': it.color
           .appendTo $circles
    $('#canvas').css 'background-color': it.color
  circleupdates.subscribe ->
    it.elem.css do
      'left': it.x
      'top': it.y
      'background-color': it.color
  circlekills.subscribe ->
    it.remove!
    circlestream.request 1
  hits.subscribe       -> $hits.html "Hits: #it"
  missclicks.subscribe -> $missclicks.html "Missed clicks: #it"
  misses.subscribe     -> $misses.html "Missed circles: #it"
  # Kick off the game.
  circlestream.request 5

还有 HTML:

<html>
    <head>
        <title>RxTest</title>
        <script type="text/javascript" src="libs/jquery-1.11.1.min.js"></script>
        <script type="text/javascript" src="libs/rx.all.js"></script>
        <script type="text/javascript" src="js/rxtest.js"></script>
        <style>
            #canvas {
                position: relative;
                width: 640px; height: 360px; background: #000000;
                color: #FFFFFF;
                overflow: hidden;
            }
            .game-container {
                position: absolute;
                background: transparent;
                color: #FFFFFF;
            }
            .circle {
                position: absolute;
                border-radius: 50%;
                width: 30px;
                height: 30px;
            }
        </style>
    </head>
    <body>
        <div id="canvas">
            <div id="circles" class="game-container"></div>
            <div id="stats" class="game-container">
                <div id="hits"></div>
                <div id="missclicks"></div>
                <div id="misses"></div>
            </div>
        </div>
    </body>
</html>

尝试删除 appendTo 中的 $(),然后只把"#circles"放在那里

class是JavaScript中的一个保留字(参见:ECMA-262 sec. 7.6.1.2),使用它可能会阻止脚本进一步执行。有几种方法可以解决这个问题。例如,您可以使用.addClass()方法来设置类。

尝试更改以下内容:

var elem = $("<div/>", {class: "circle"});
elem.css({'background-color': color})
    .appendTo($("#circles"));

对此:

var elem = $("<div/>").addClass("circle");
elem.css({'background-color': color})
    .appendTo($("#circles"));

看看是否有帮助。

好吧,所以,我离得很远。 显然,RxJS为每个订阅者创建了一个新的圆圈div。在本例中,每个圈子进行了 4 个事件订阅。我通过使用Rx.Observable.prototype.publish()解决了这个问题。

工作 JSFiddle: http://jsfiddle.net/u3Lf6d26/1/