【问题标题】:How to correctly update the text value of an input element in a d3.js transition如何在 d3.js 转换中正确更新输入元素的文本值
【发布时间】:2014-07-29 12:24:32
【问题描述】:

我一直在尝试,逐步将一些非常好的但静态和非 d3 code 转换为 d3.js 可视化中的动态动画。

(虽然与这个问题没有直接关系,但原始代码“简单”-haha- 接受用户提供的和弦名称,例如“Amaj7”,将其分解为组件音符并显示相关波形。我正在尝试来创建基于和弦名称数组的过渡驱动动画。)

就我而言,对于每次成功代码更新(到 d3.js 友好版本),源代码都会被保存以作为与下一个的工作比较。

在当前的代码更新中,我在尝试合并转换时遇到了一个小故障。过渡本身已得到充分证明,并且(通过日志记录)可以看到按预期触发。

在转换期间,所需的属性值更改(要处理的下一个和弦名称,以及立即转换的目标)失败。将以前的(工作)版本与当前版本进行比较:

初始创建,两者通用,但在单独的文件中,因此元素只能通过 DOM 访问

var input = container
.append("input")
.attr("class", wavebase.animation_type + "_input")
.attr("id", "chordinput")
.attr("type", "text")
.attr("value","Amaj7");

var input = document.getElementById('chordinput');

input.addEventListener('change', inputChanged, false);
inputChanged.call(input);

和(过渡前):

input.setAttribute("value", (waveplot.chordname + "\x0A")); 
inputChanged.call(input);

让我们明确一点:上述工作

var input = container
.select("#chordinput")

input.on('change', inputChanged, false);
inputChanged.call(input);

后来,这都没有:

input
.transition()
.text(function() {
    return (waveplot.chordname + "\x0A");
})

..也不是这个:

input
.transition()
.attr("value", function() {
    return (waveplot.chordname + "\x0A");
});

..nor 变体减去返回字符 ("\x0A") 会导致更新输入元素的值字段。顺便说一下,waveplot.chordname 总是正确定义的。

鉴于新代码中甚至连原来的 Amaj7 都无法识别,我的直觉是问题出在该行

input.on('change', inputChanged, false);

显然,在播放过渡时,我的目标是使用这条线来捕获多个事件。我做错了什么或做错了什么?例如,我是否必须使用不同的触发器(“提交”和“点击”都没有任何影响)、使用 d3.dispatch(),或者甚至将每个事件映射到它自己的 ('change.n') 处理程序?

注意:虽然我很想在 jsfiddle 中演示这个,但整个东西都嵌入在一个框架中,也就是目前不切实际..

谢谢 暴徒

【问题讨论】:

    标签: javascript events input d3.js transitions


    【解决方案1】:

    这里发生了几件事,但都与 d3 没有直接关系。但是,在您修复代码时,还需要注意一些与 d3 相关的事情,所以我在下面用斜体字表示了它们。

    首先,设置.text()<input> 不起作用,因为它会更改.textContent 属性(被忽略——输入元素为空)。

    即使您在有效的文本容器元素上使用了transition().text(),您也不会看到“过渡”——文本只会在过渡延迟后立即发生变化。

    其次,输入的value属性value属性相同(即element.value) .在任何用户 脚本交互之前,该属性(即您将包含在标记中的内容)定义输入元素的 initial 值。在页面加载后更改它没有效果。相比之下,该属性定义了字段的当前值,无论您是在脚本中更改它还是用户通过键入来更改它。

    请看这个小提琴(它只使用纯 Javascript,而不是 d3):
    http://fiddle.jshell.net/FVF29/

    var i = document.getElementById("i");
    i = i;
    i.setAttribute("value", "Stuff");
    i.value="Good Stuff";
    i.setAttribute("value", "Other Stuff");
    

    setAttribute 调用都不影响显示——文本框包含“Good Stuff”——尽管如果您检查 DOM,您会看到属性已更改。

    虽然不经常使用,但 d3 有一种方法可以更改选择中元素的元素属性,selection.property(propertyName, valueOrFunction)。但是,没有等效的转换函数。

    您可以提出一个有效的功能请求,即应该有一个transition.property() 函数。根据您的示例,我当然可以看到它的用途-也许您有一个数字滑块或颜色输入,并且您希望显示的值平滑地变化,而不是立即跳到您正在设置的值。

    但是,这在您的情况下仍然无法正常工作。假设属性转换函数的实现与属性或样式转换相同,则字符串值的默认转换将字符串分为数字段和非数字段。非数字段立即改变,数字转换。如果您从“Cmin6”更改为“Amaj7”,这将是奇怪和随机的——您最终会得到一个像“Amaj6.569087098608760876”这样的和弦!

    总结:我不知道您为什么要使用转换来更改文本字段,或者您期望中间值是什么。如果您清楚地知道如何计算中间值,请使用直接设置 this.value 的自定义补间函数。 (有关如何执行此操作的示例,请参阅我为 this answer, which uses a custom tween to set this.textContent 创建的小提琴。)否则,跳过转换并使用:

    input.property("value", waveplot.chordname);
    

    【讨论】:

    • 过渡直接作用于文本输入字段(而不是简单地激活背景波形绘图功能)的原因是我希望用户能够输入、可视化(并最终听)他们自己的替代和弦,同时逐步进行和弦进行)。顺便说一句,我可能已经为此奋斗了好几天:很棒的答案。
    • 在此期间,我已经能够继续前进。一旦我的动画在各个方面都能正常工作,我会记录最终的解决方案。
    • 很高兴听到这个消息。和弦波形是一种有趣的可视化效果,我一直想亲自尝试,但一直没有动手。
    猜你喜欢
    • 1970-01-01
    • 2019-05-27
    • 1970-01-01
    • 2011-04-12
    • 1970-01-01
    • 2013-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多