简体   繁体   中英

JavaScript slice / substring returning undefined only when replacing HTML innerText

So, I have programmed a simple RGB slider which shows its result on a HTML canvas. Everything works except a slice / substring : for some reason, when setting it to a variable or changing the innerText of a <span> it returns undefined .

 const $ = ele => document.querySelector(ele), numToHex = num => parseInt(num, 10).toString('16').padStart(2, '0'), c = $('#canvas').getContext('2d') var rsp = $('#rspan'), gsp = $('#gspan'), bsp = $('#bspan'), rvalue, gvalue, bvalue $('#rrange').oninput = () => { rvalue = `#${numToHex($('#rrange').value).toUpperCase()}0000` rsp.innerText = rvalue rsp.style.color = rvalue updateCanvas() } $('#grange').oninput = () => { gvalue = `#00${numToHex($('#grange').value).toUpperCase()}00` gsp.innerText = gvalue gsp.style.color = gvalue updateCanvas() } $('#brange').oninput = () => { bvalue = `#0000${numToHex($('#brange').value).toUpperCase()}` bsp.innerText = bvalue bsp.style.color = bvalue updateCanvas() } function updateCanvas(rval = rvalue, gval = gvalue, bval = bvalue) { console.log(rval.substring(0, 3)) // This works let arr = [rval.substring(0, 3), gval.substring(3, 5), bval.substring(-2)] c.fillStyle = arr.join('') // Throws error c.fillRect(0, 0, 250, 250) }
 input { width: 300px; }
 <!DOCTYPE html> <html> <head> <title>RGB Slider</title> </head> <body> <canvas id="canvas" width="250" height="250"></canvas> <div id="rdiv"> <input type="range" min="0" max="255" id="rrange" /> <span id="rspan"></span> </div> <div id="gdiv"> <input type="range" min="0" max="255" id="grange" /> <span id="gspan"></span> </div> <div id="bdiv"> <input type="range" min="0" max="255" id="brange" /> <span id="bspan"></span> </div> </body> </html>

Why is this happening? It also throws the same error with slice . And why does it work in the prior console.log statement?

You currently don't always define rvalue , gvalue , and bvalue - they start out undefined , and all 3 only become assigned to once every slider has been changed at least once. Before that point, the updateCanvas :

function updateCanvas(rval = rvalue, gval = gvalue, bval = bvalue) {

will have at least one undefined parameter, so trying to access .substring on those undefined parameters will throw.

Set the color values to default to the middle of the range, #808080 :

rvalue = '#808080',
gvalue = '#808080',
bvalue = '#808080';

You also need to slice the substrings properly when constructing the array - take 2 characters from each of red, green, and blue, then put them together and prefix them with # :

 const $ = ele => document.querySelector(ele), numToHex = num => parseInt(num, 10).toString('16').padStart(2, '0'), c = $('#canvas').getContext('2d') var rsp = $('#rspan'), gsp = $('#gspan'), bsp = $('#bspan'), rvalue = '#800000', gvalue = '#808080', bvalue = '#808080'; $('#rrange').oninput = () => { rvalue = `#${numToHex($('#rrange').value).toUpperCase()}0000` rsp.innerText = rvalue rsp.style.color = rvalue updateCanvas() } $('#grange').oninput = () => { gvalue = `#00${numToHex($('#grange').value).toUpperCase()}00` gsp.innerText = gvalue gsp.style.color = gvalue updateCanvas() } $('#brange').oninput = () => { bvalue = `#0000${numToHex($('#brange').value).toUpperCase()}` bsp.innerText = bvalue bsp.style.color = bvalue updateCanvas() } function updateCanvas(rval = rvalue, gval = gvalue, bval = bvalue) { let arr = [rval.substring(1, 3), gval.substring(3, 5), bval.substring(5, 7)] console.log(arr); c.fillStyle = '#' + arr.join('') // Throws error c.fillRect(0, 0, 250, 250) }
 input { width: 300px; }
 <!DOCTYPE html> <html> <head> <title>RGB Slider</title> </head> <body> <canvas id="canvas" width="250" height="250"></canvas> <div id="rdiv"> <input type="range" min="0" max="255" id="rrange" /> <span id="rspan"></span> </div> <div id="gdiv"> <input type="range" min="0" max="255" id="grange" /> <span id="gspan"></span> </div> <div id="bdiv"> <input type="range" min="0" max="255" id="brange" /> <span id="bspan"></span> </div> </body> </html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM