JavaScript 根本没有在 HTML 文件中运行
Posted
技术标签:
【中文标题】JavaScript 根本没有在 HTML 文件中运行【英文标题】:JavaScript not running at all in HTML file 【发布时间】:2021-08-09 08:53:30 【问题描述】:我正在尝试制作签名板,但 JS(涂鸦线)在开发沙箱中工作,但在我合并文件时却不行。在关闭正文标签之前,我已将我的 CSS 放在头部标签和脚本之间,以允许 JS 在其他组件运行后运行。不确定是什么导致它无法运行。这里是初学者,所以如果我的问题太入门级,我深表歉意。任何帮助将不胜感激。
<html>
<head>
<style>
*,
*::before,
*::after
box-sizing: border-box;
body
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
height: 100vh;
width: 100%;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
margin: 0;
padding: 32px 16px;
font-family: Helvetica, Sans-Serif;
.signature-pad
position: relative;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
font-size: 10px;
width: 100%;
height: 100%;
max-width: 700px;
max-height: 460px;
border: 1px solid #e8e8e8;
background-color: #fff;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.27), 0 0 40px rgba(0, 0, 0, 0.08) inset;
border-radius: 4px;
padding: 16px;
cursor: crosshair;
cursor: url('https://staging-dovetail.kinsta.cloud/wp-content/uploads/2021/05/Pen-Cursor-1.png') 53 53, crosshair;
.signature-pad::before,
.signature-pad::after
position: absolute;
z-index: -1;
content: "";
width: 40%;
height: 10px;
bottom: 10px;
background: transparent;
box-shadow: 0 8px 12px rgba(0, 0, 0, 0.4);
.signature-pad::before
left: 20px;
-webkit-transform: skew(-3deg) rotate(-3deg);
transform: skew(-3deg) rotate(-3deg);
.signature-pad::after
right: 20px;
-webkit-transform: skew(3deg) rotate(3deg);
transform: skew(3deg) rotate(3deg);
.signature-pad--body
position: relative;
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
border: 1px solid #f4f4f4;
canvas
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
border-radius: 4px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.02) inset;
.signature-pad--footer
color: #C3C3C3;
text-align: center;
font-size: 1.2em;
margin-top: 8px;
.signature-pad--actions
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
margin-top: 8px;
#github img
border: 0;
#fileupload
display: none;
form
display: table-row;
margin-right: 5px;
span[role=button]
display: table-cell;
font-size: 1.2em;
span[role=button],
button
cursor: pointer;
background-color: #e1e1e1;
color: #000000;
border: none;
padding: 8px;
margin-bottom: 8px;
@media (max-width: 940px)
#github img
width: 90px;
height: 90px;
</style>
</head>
<body>
<div id="signature-pad" class="signature-pad">
<div class="signature-pad--body">
<canvas>
Update your browser to support the canvas element!
</canvas>
</div>
<div class="signature-pad--footer">
<div class="description">Sign above</div>
<div class="signature-pad--actions">
<form action="#" enctype="multipart/form-data">
<label for="fileupload" id="buttonlabel">
</label>
<input type="file" id="fileupload" accept="image/*">
</form>
<div>
<button type="button" class="button clear" data-action="clear">Clear</button>
</div>
</div>
</div>
</div>
<script>
const wrapper = document.getElementById("signature-pad")
const clearButton = wrapper.querySelector("[data-action=clear]")
const changeColorButton = wrapper.querySelector("[data-action=change-color]")
const undoButton = wrapper.querySelector("[data-action=undo]")
const savePNGButton = wrapper.querySelector("[data-action=save-png]")
const saveJPGButton = wrapper.querySelector("[data-action=save-jpg]")
const saveSVGButton = wrapper.querySelector("[data-action=save-svg]")
const canvas = wrapper.querySelector("canvas")
const fileSelector = document.getElementById('fileupload')
// https://medium.com/the-everyday-developer/detect-file-mime-type-using-magic-numbers-and-javascript-16bc513d4e1e
const verifyAndSetPictureAsBackground = (event) =>
const file = event.target.files[0]
const fReader = new FileReader()
fReader.onloadend = (e) =>
if (e.target.readyState === FileReader.DONE)
const uint = new Uint8Array(e.target.result)
let bytes = []
uint.forEach((byte) => bytes.push(byte.toString(16)))
const hex = bytes.join('').toUpperCase()
if (!(getMimeType(hex) === 'image/png' || getMimeType(hex) === 'image/gif' || getMimeType(hex) === 'image/jpeg'))
alert('Please choose a picture(.png, .gif, or .jpeg)')
// https://***.com/a/35323290/1904223
file = null
fileSelector.value = ''
if (!/safari/i.test(navigator.userAgent))
fileSelector.type = ''
fileSelector.type = 'file'
if (file)
const dataURL = window.URL.createObjectURL(file)
signaturePad.fromDataURL(dataURL)
fReader.readAsArrayBuffer(file.slice(0, 4))
const getMimeType = (signature) =>
switch (signature)
case '89504E47':
return 'image/png'
case '47494638':
return 'image/gif'
case 'FFD8FFDB':
case 'FFD8FFE0':
case 'FFD8FFE1':
return 'image/jpeg'
default:
return 'Not allowed filetype'
fileSelector.addEventListener('change', verifyAndSetPictureAsBackground, false)
const signaturePad = new SignaturePad(canvas,
// It's Necessary to use an opaque color when saving image as JPEG
// this option can be omitted if only saving as PNG or SVG
backgroundColor: 'rgb(255, 255, 255)'
)
// Adjust canvas coordinate space taking into account pixel ratio,
// to make it look crisp on mobile devices.
// This also causes canvas to be cleared.
const resizeCanvas = () =>
// When zoomed out to less than 100%, for some very strange reason,
// some browsers report devicePixelRatio as less than 1
// and only part of the canvas is cleared then.
const ratio = Math.max(window.devicePixelRatio || 1, 1)
// This part causes the canvas to be cleared
canvas.width = canvas.offsetWidth * ratio
canvas.height = canvas.offsetHeight * ratio
canvas.getContext("2d").scale(ratio, ratio)
// This library does not listen for canvas changes, so after the canvas is automatically
// cleared by the browser, SignaturePad#isEmpty might still return false, even though the
// canvas looks empty, because the internal data of this library wasn't cleared. To make sure
// that the state of this library is consistent with visual state of the canvas, you
// have to clear it manually.
signaturePad.clear()
// On mobile devices it might make more sense to listen to orientation change,
// rather than window resize events.
window.onresize = resizeCanvas
resizeCanvas()
const download = (dataURL, filename) =>
const blob = dataURLToBlob(dataURL)
const url = window.URL.createObjectURL(blob)
const a = document.createElement("a")
a.style = "display: none"
a.href = url
a.download = filename
document.body.appendChild(a)
a.click()
window.URL.revokeObjectURL(url)
// One could simply use Canvas#toBlob method instead, but it's just to show
// that it can be done using result of SignaturePad#toDataURL.
function dataURLToBlob(dataURL)
// Code taken from https://github.com/ebidel/filer.js
const parts = dataURL.split('base64,')
const contentType = parts[0].split(":")[1]
const raw = window.atob(parts[1])
const rawLength = raw.length
const uInt8Array = new Uint8Array(rawLength)
for (let i = 0; i < rawLength; ++i)
uInt8Array[i] = raw.charCodeAt(i)
return new Blob([uInt8Array], type: contentType )
clearButton.addEventListener("click", () => signaturePad.clear())
undoButton.addEventListener("click", () =>
const data = signaturePad.toData()
if (data)
data.pop() // remove the last dot or line
signaturePad.fromData(data)
)
changeColorButton.addEventListener("click", () =>
const r = Math.round(Math.random() * 255)
const g = Math.round(Math.random() * 255)
const b = Math.round(Math.random() * 255)
const color = "rgb(" + r + "," + g + "," + b +")"
signaturePad.penColor = color
)
savePNGButton.addEventListener("click", () =>
if (signaturePad.isEmpty())
alert("Please provide a signature first.")
else
const dataURL = signaturePad.toDataURL()
download(dataURL, "signature.png")
)
saveJPGButton.addEventListener("click", () =>
if (signaturePad.isEmpty())
alert("Please provide a signature first.")
else
const dataURL = signaturePad.toDataURL("image/jpeg")
download(dataURL, "signature.jpg")
)
saveSVGButton.addEventListener("click", () =>
if (signaturePad.isEmpty())
alert("Please provide a signature first.")
else
const dataURL = signaturePad.toDataURL('image/svg+xml')
download(dataURL, "signature.svg")
)
</script>
</body>
</html>
【问题讨论】:
【参考方案1】:当您在浏览器中打开此文件时,您需要查看“开发人员工具”以在控制台中查找错误(如果您不知道如何操作:尝试右键单击您的网页并选择“检查”来自上下文菜单)
控制台会显示:
Uncaught ReferenceError: SignaturePad is not defined
file:test.html:233
在第 233 行查找
const signaturePad = new SignaturePad(....
类 SignaturePad 在哪里定义?您是否将其放在单独的文件中?
【讨论】:
以上是关于JavaScript 根本没有在 HTML 文件中运行的主要内容,如果未能解决你的问题,请参考以下文章
Cordova + Xcode 7.3 (html + Javascript) 在构建和模拟时未更改或更新
JavaScript 和 HTML 文件没有在 UIWebView 中运行