Similar to Rahul Metangale's post above, I found SVG rectangles to be the best approach. This works well to remove & re-create the label background each time the map is redrawn (after pan or zoom).
function turnOnLabels() {
var labelLayerNode = labelLyr.getNode();
if (!labelLayerNode || labelLayerNode === null) {
return;
}
var textLabels = query("text", labelLayerNode);
array.forEach(textLabels, function (label) {
var txtContent = label.textContent;
label.textContent = txtContent.replace("null", "");
var lBox = label.getBBox();
label.innerHTML = label.textContent
var rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
rect.setAttribute("x", lBox.x);
rect.setAttribute("y", lBox.y);
rect.setAttribute("width", lBox.width + 1); //added a little margin
rect.setAttribute("height", lBox.height - 2); //trimmed down margin
rect.setAttribute("fill", "rgba(255,255,255,0.9)"); //opacity of 0.9 can be adjusted
labelLayerNode.insertBefore(rect, label);
});
}
function turnOffLabels() {
var labelLayerNode = labelLyr.getNode();
if (!labelLayerNode) { return; }
var elements = labelLayerNode.querySelectorAll("rect");
for (var i = 0; i < elements.length; ++i) {
var elem = elements;
labelLayerNode.removeChild(elem);
}
}
app.map.on('update-start', function () {
turnOffLabels();
});
app.map.on('update-end', function () {
turnOnLabels();
});
Edit: It works well enough for visual display on the screen, but I discovered these svg rectangles are lost when I export to PDF using PrintTask (esri/tasks/PrintTask). I am going to contact ESRI about this, but I would be interested in knowing if there is any workaround. Here is a JSFiddle example to illustrate the problem: http://jsfiddle.net/r2nnrL3t
Edit #2: I confirmed with ESRI support services this is a known issue:
The bug id is NIM090851 : Export Web Map Task cannot print a map using SVG symbol types in JavaScript API 3.4. The status of the bug is set to "Tech review Complete" which means that the bug has been reviewed by the Technical Leads and now it's being reviewed by the Product Engineers, and then it will be assigned to the development team for a fix.
Therefore, my solution is to use LabelClass with halo color and halo size properties (Brendan Madden's solution below). It is compatible with PrintTask and gets the job done to provide a background for contrast.