如何正确更新d3.js转换中的输入元素的文本值 [英] How to correctly update the text value of an input element in a d3.js transition

查看:212
本文介绍了如何正确更新d3.js转换中的输入元素的文本值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试,一步一步,转换一些非常好,但静态&非d3 代码用于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值,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);
});

..变量减去返回字符(\x0A)会导致输入更新元素的值字段。



考虑到即使原来的Amaj7在新的代码中也无法识别,我的直觉是,问题出在于

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

很明显,随着游戏的过渡,我的目标是使用这一行捕捉多个事件。我没有做什么,或做错了什么?例如,我必须使用不同的触发器(既不'submit'也不'click'有任何影响),使用d3.dispatch(),甚至映射每个事件它自己的('change.n')处理程序?



注意:就像我想在一个jsfiddle的例子中演示这一点,整个事情嵌入在一个框架,现在是不切实际的。



感谢
Thug

解决方案

它们都不与d3直接相关。但是,在修复代码时,还需要注意一些d3相关的事情,所以我在下面用斜体表示。



首先,设置 .text()不能在< input> ; ,因为它改变了 .textContent 属性(被忽略 - 输入元素为空)。



即使在有效的文本容器元素上使用了 transition()。text()将不会看到过渡 - 文字会在转换延迟后立即更改。

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



查看此小提示(仅使用纯JavaScript,而不是d3):

http://fiddle.jshell。 net / FVF29 /

  var i = document.getElementById(i); 
i = i;
i.setAttribute(value,Stuff);
i.value =好东西;
i.setAttribute(value,Other Stuff);

setAttribute 调用影响显示 - 文本框包含好东西 - 虽然如果您检查DOM,您会看到属性已更改。



虽然不经常使用,但d3用于更改选择中元素的元素属性的方法, 选择。属性(propertyName,valueOrFunction)

transition.property()
函数。根据你的例子,我当然可以看到它的一个用法 - 也许你有一个数字滑块或颜色输入,你希望显示的值更改顺利,而不是瞬间跳转到你设置它的值。



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



总之:我不知道为什么要使用转换来更改文本字段,或者你期望的值之间的值。如果您明确想要如何计算中间值之间的值,请使用直接设置 this.value 的自定义补间函数。 (有关如何执行此操作的示例,请参阅我为这个答案,它使用自定义补间来设置 this.textContent 。)否则,跳过转换并使用:

  input.property(value,waveplot.chordname); 


I've been trying, step by step, to convert some very nice but static & non-d3 code for dynamic animation in a d3.js visualisation.

(Though not directly relevant to this problem, the original code 'simply' -haha- accepts a user-supplied chordname such as 'Amaj7', breaks it down into it's component notes and displays the associated waveforms. I'm trying to create an transition-driven animation based on an array of chordnames.)

For my part, for each successful code update (to a d3.js friendly version) achieved, the source code was saved to act as a working comparison with the next.

In the current update to the code, I've hit a glitch trying to incorporate a transition. The transition itself is well proven, and (by means of logging) can be seen to fire as expected.

During the transition, the desired attribute value changes (the next chordname to be handled, and the goal of the immediate transition) are failing. Comparing the previous (working) version with the current:

Initial creation, common to both, but in a separate file and so element is accessible only via the DOM

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

Old

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

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

and (pre-transition):

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

Let's be clear: the above works.

New

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

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

Later, neither this:

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

..nor this:

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

..nor variants minus the return character ("\x0A") result in update of the input element's value field. waveplot.chordname is, incidentally, always correctly defined.

Given that not even the original Amaj7 is not recognised in the new code, my gut feeling is that the problem lies with the line

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

Clearly, with transitions in play, my aim is to trap multiple events using this line. What am I failing to do, or doing wrong? Must I for example use a different trigger (neither 'submit' nor 'click' have any impact), use d3.dispatch(), or even map each event to it's own ('change.n') handler?

Note: much as I'd like to demo this in the likes of a jsfiddle, the whole thing is embedded in a framework, aka for the moment impractical..

Thanks Thug

解决方案

There are a couple things going on here, neither of which are directly related to d3. However, there are also some d3-related things to be aware of as you fix your code, so I've indicated them in italics below.

First, setting .text() won't work on an <input>, because it changes the .textContent property (which is ignored -- input elements are empty).

Even if you used transition().text() on a valid text container element, you wouldn't see a "transition" -- the text would just instantaneously change after the transition delay.

Second, the value attribute of an input is not the same as the value property (i.e. element.value). The attribute (which is what you'd include in the markup) defines the initial value for the input element, before any user or script interaction. Changing it after the page is loaded has no effect. The property, in contrast, defines the current value of the field, regardless of whether you change it in the script or whether the user changes it by typing.

See this fiddle (which only uses plain Javascript, not 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");

Neither setAttribute call affects the display -- the text box contains "Good Stuff" -- although if you check the DOM you'll see that the attribute has been changed.

Although it's not often used, d3 has a method for changing element properties for the elements in a selection, selection.property(propertyName, valueOrFunction). However, there is no equivalent function for transitions.

You could make a valid feature request that there should be a transition.property() function. Based on your example, I can certainly see a use for it -- maybe you have a number slider or color input, and you want the displayed value to change smoothly instead of instantaneously jumping to the value you're setting it.

However, that still wouldn't work well in your case. Assuming the property transition function was implemented the same as an attribute or style transition, the default transition for a string value breaks the string into number and non-number segments. The non-number segments change immediately, the numbers transition. Which would be weird and random if you were changing from "Cmin6" to "Amaj7" -- you'd end up with a chord like "Amaj6.569087098608760876"!

In conclusion: I have no idea why you want to use a transition to change the text field, or what you expect the in-between values to be. If you have a clear idea of how you want in-between values to be calculated, use a custom tween function that directly sets this.value. (For an example of how to do this, see the fiddle I created for this answer, which uses a custom tween to set this.textContent.) Otherwise, skip the transition and just use:

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

这篇关于如何正确更新d3.js转换中的输入元素的文本值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆