bongbang
bongbang

Reputation: 1712

D3: change html in transition

In this (broken) minimal example, I want the text to fade out, change while invisible, and reappear with the changed content. This should be simple (no cross-fading), but the error message complains that .html is not a function.

<!DOCTYPE html>
<title>Image mask</title>

<script type="text/javascript"
  src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js">
</script>
<body>
</body>
<script>
var textbox = d3.select('body').append('div');

textbox
	.html('Click me.')
	.style('cursor','pointer');

var i = 0;
textbox.on('click', function() {
	i++;
	textbox.transition()
		.style('opacity', 0)
	.transition().duration(300)
	.html('Click me. <strong>' + i + '</strong>')
	.transition().transition()
		.style('opacity', 1);
});
</script>

PS I found an example for cross-fading, but it seems unnecessary complicated (since I don't want cross-fading) and requires version 4's .active method.

Update. It "works" if .html is replaced with .text, but I really need the content to be parsed.

Upvotes: 1

Views: 1668

Answers (1)

meetamit
meetamit

Reputation: 25157

Turns out (as you've discovered) that d3.transition doesn't have a .html() method. This is confirmed by the lack of transition.html in the docs here. That's not totally unexpected, considering that there is no obvious way to interpret what it means to do a continuous transition of the innerHtml value, but then again .remove() is "transitionable", in the same way you would want .html() to be transitioned (i.e. non-continuously, right at the end of the transition).

Oh well. You can still do what you want to do by essentially subscribing to the end of the transition, using the .each("end", function() {}) mechanism:

<!DOCTYPE html>
<title>Image mask</title>

<script type="text/javascript"
  src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js">
</script>
<body>
</body>
<script>
var textbox = d3.select('body').append('div');

textbox
  .html('Click me.')
  .style('cursor','pointer');

var i = 0;
textbox.on('click', function() {
  i++;
  textbox.transition()
    .style('opacity', 0)
    .each("end", function() {
      d3.select(this)
        .html('Click me. <strong>' + i + '</strong>')
        .transition()
        .style('opacity', 1);
    })
});
</script>

Upvotes: 5

Related Questions