者 | Mateusz Iwaniuk
譯者 | 明明如月,責(zé)編 | 夕顏
出品 | CSDN(ID:CSDNnews)
文章配套代碼: https://github.com/iwaniukooo11/email-sender
現(xiàn)在,即使是創(chuàng)建最基本的網(wǎng)站,程序員也必須使用現(xiàn)代的功能和技術(shù)。甚至像為你的朋友創(chuàng)建簡單的投資組合這樣的基本項目也可能涉及到一些問題,比如從聯(lián)系人表單接收數(shù)據(jù)。有很多方法可以讀取這些數(shù)據(jù)。你可以將表單與數(shù)據(jù)庫連接起來,然后從數(shù)據(jù)庫中讀取傳入的消息來實現(xiàn)功能,但這樣做會給不懂技術(shù)的客戶造成困難。
你為什么不通過發(fā)送電子郵件傳輸信息?
不使用數(shù)據(jù)庫就能接收到傳入的消息,絕對是最佳選擇,也是最方便用戶的選擇。但問題來了—如何實現(xiàn)呢?你可能認為需要使用某種后端語言。
實際上,你不必使用任何如 php 或 python 這種后端語言,你甚至不需要用到 node.js!你需要的就是一個簡單的EmailJS 庫。
本文將介紹下面兩個重要功能:
配置 emailjs 帳戶
使用 JS 發(fā)送電子郵件
請注意,在我的項目中,我使用了 gulp 和 webpack,我在 src 文件夾存放源碼,dist 存放最終發(fā)布版本的代碼。
我將分 5 個步驟向你展示如何從頭開始構(gòu)建電子郵件發(fā)送器。
步驟1-用 HTML 創(chuàng)建表單
首先需要創(chuàng)建一個 HTML 表單。你不必放置像 required 或 max 這種驗證屬性,因為稍后,preventDefault 函數(shù)將在你的提交事件上運行,它會讓這些屬性的處理失效。
表單中最重要的是為每個輸入放置 name 屬性,后面會用到。
我的非常簡單的表單是這樣的:
src/html/index.html
<form class="form">
<input name='name' type="text" placeholder="Your name..." class="form__input" />
<input name='topic' type="text" placeholder="Topic..." class="form__input" />
<textarea name='message' type="text" placeholder="Your Message..." class="form__input" ></textarea>
<input type="submit" value="send" class="form__input form__input--button">
</form>
步驟2-注冊成為 email 用戶
要配置你的電子郵件,你必須注冊電子郵件服務(wù)。別擔(dān)心—使用這個網(wǎng)站非常方便和省時。
登入后,系統(tǒng)會詢問你的電子郵件服務(wù),它位于個人電子郵件服務(wù)區(qū)(personal email service)。在我的例子中,我選擇了 gmail。
然后,你需要連接你的 gmail 帳戶。這將用來發(fā)送電子郵件給你客戶。例如,如果你關(guān)聯(lián)了 xyz@gmail.com 賬戶,你后續(xù)發(fā)送的郵件都將從這個郵箱發(fā)出。所以不要擔(dān)心“ Send email on your behalf” 這個授權(quán)信息—這正是你需要的!
連接完 gmail 賬戶后,點擊添加服務(wù)(add service)按鈕。
步驟3-創(chuàng)建郵件模板
如果你已經(jīng)成功連接了你的 gmail 賬戶,你現(xiàn)在應(yīng)該在信息中心中。現(xiàn)在需要創(chuàng)建電子郵件模板了。
切換到電子郵件模板卡,并單擊創(chuàng)建一個新的模板(create a new template)。界面非常友好,所以創(chuàng)建模板不會有任何問題。
你可以選擇模板的名稱和 ID。我稱之為“我的神奇模板(my_amazing_template)”。
接下來,你必須指定郵件的內(nèi)容。
模板的變量值來自 input 中的 `name` 屬性。你已將變量插入`{{{}}}`符號中。
不要忘記在“收件人”部分 (右側(cè)) 添加電子郵件地址。你的電子郵件將被發(fā)送到該電子郵件地址上。截圖中的收件人郵箱是我自己的公司郵箱。
這是我的簡單模板,它使用來自 HTML 表單里的 3 個變量。我還指定了接收電子郵件的主題。
步驟4-保存 API 密鑰
這部分沒什么特別的。Emailjs 共享授權(quán) API 密鑰,將在發(fā)送電子郵件時使用。當(dāng)然,放這些鑰匙最好的地方是`.env` 配置。但是因為我使用的是簡單的靜態(tài)文件,我不想使用服務(wù)器配置,所以我將它們保存在 apikeys 文件中,然后再將它們導(dǎo)入。
你的 USER_ID 位于 Account > API Keys 菜單下。
TEMPLATE_ID 位于模板的標題下面。
這是我基于不存在的 keyssrc / js / apikeys. js 的示例配置.
src/js/apikeys.js
export default {
USER_ID :'user_DPUd-rest-of-my-id',
TEMPLATE_ID:'my_amazing_template'
}
如果需要將源碼發(fā)布到 GITHUB,不要忘記將 APIKEYS 文件添加到 .GITIGNORE文件中
現(xiàn)在是該項目最后也是最重要的部分的了。現(xiàn)在我們必須使用 javascript 發(fā)送電子郵件。
首先,你必須下載 emailjs 包。
npm i emails-com
然后,轉(zhuǎn)到 js 文件,導(dǎo)入庫和 apikeys。
src/js/main.js
import emailjs from 'emailjs-com'
import apiKeys from './apikeys'
現(xiàn)在是編寫發(fā)送電子郵件功能的時候了
src/js/main.js
const sendEmail = e => {
e.preventDefault
emailjs
.sendForm('gmail', apiKeys.TEMPLATE_ID, e.target, apiKeys.USER_ID)
.then(
result => {
console.log(result.text)
},
error => {
console.log(error.text)
}
)
}
sendForm 函數(shù)有4個參數(shù):
你的電子郵件的 ID,在這里:
TEMPLATE_ID 來自 apikey 文件,
事件對象來自你的表單提交
USER_ID 來自 apikey 文件,
最后,查找表單并添加提交事件監(jiān)聽器:
src/js/main.js
const form = document.querySelector('.form')
form.addEventListener('submit',sendEmail)
正如我前面提到的,由于 `preventDefault` 函數(shù),屬性驗證將無法工作。你必須使用 JS 自己進行驗證和清除輸入。
以上就是全部內(nèi)容,接下來讓我們測試一下。
填寫頁面上的表單并發(fā)送。
我收到電子郵件,內(nèi)容正是根據(jù)我們的模板和表單數(shù)據(jù)渲染出來的。
通過上圖可以看出,所有的變量的值都填充到了正確的位置上。
通過本文的介紹你會發(fā)現(xiàn)用 JS 發(fā)送郵件并非難事。
使用 emailjs,你可以簡單的方式發(fā)送電子郵件。
我相信你未來的用戶會很高興收到來自他們網(wǎng)頁上表單填寫數(shù)據(jù)的t郵件,相信本文對你有幫助。
這篇文章的配套代碼在這里: https://github.com/iwaniukooo11/email-sender
原文鏈接:
https://dev.to/iwaniukooo11/send-e-mails-directly-from-front-end-with-js-5d7d
本文為CSDN翻譯文章,轉(zhuǎn)載請注明出處。
?我們想研發(fā)一個機器學(xué)習(xí)框架,6 個月后失敗了
?生產(chǎn)型機器學(xué)習(xí)已經(jīng)沒那么困難了?
?視頻 | 你不知道的"開源"60年秘史
?GitHub標星10,000+,Apache項目ShardingSphere的開源之路
?阿里技術(shù)專家告訴你,如何畫出優(yōu)秀的架構(gòu)圖?
?加拿大API平臺如何做到30%為中國明星項目?創(chuàng)業(yè)老兵這樣說……
HTML Webpack Plugin這是一個webpack插件,它簡化了HTML文件的創(chuàng)建,以服務(wù)于你的webpack bundle。這對于在文件名中包含哈希的webpack包特別有用,因為文件名會改變每次編譯。您可以讓插件為您生成一個HTML文件,或者使用lodash模板提供您自己的模板,或者使用您自己的加載器。
針對webpack的版本,需要安裝對應(yīng)不同的版本。
webpack4
npm i --save-dev html-webpack-plugin@4
webpack5
npm i --save-dev html-webpack-plugin
這個插件會為你生成一個HTML5文件,其中包含了使用script標簽的所有webpack的bundle。
只需將插件添加到webpack配置中,如下所示:
const path = require("path")
const HtmlWebpackPlugin = require("html-webpack-plugin")
module.exports = {
entry: "./src/index.js",
output: {
filename:"index_bundle.js",
path: path.resolve(__dirname,"dist")
},
plugins: [
new HtmlWebpackPlugin()
]
}
這將生成一個包含以下內(nèi)容的文件dist/index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Webpack App</title>
</head>
<body>
<script src="index_bundle.js"></script>
</body>
</html>
如果您有多個webpack入口點,它們都將與script標簽一起包含在生成的HTML中。
如果你在webpack的輸出中有任何CSS資產(chǎn)(例如,用mini-css-extract-plugin提取的CSS),那么這些將包含在HTML頭部的標簽中。
如果你有使用它的插件,html-webpack-plugin應(yīng)該在任何集成插件之前。
你可以傳遞一個配置選項到html-webpack-plugin。允許的值如下:
類型:String
默認值:Webpack App
描述:要用于生成的HTML文檔的標題。
類型:String或Function
默認值:index.html
描述:要寫入HTML的文件的文件名。默認為index.html。您也可以在這里指定一個子目錄(例如:assets/admin.html)。占位符[name]將被條目名稱替換。也可以是一個函數(shù),例如(entryName) => entryName + '.html'。
類型:String
默認值:空
描述:默認情況下,它將使用src/index.ejs(如果存在的話)。
類型:string|Function|false
默認值:false
描述:可以用來代替模板提供一個內(nèi)聯(lián)模板。
類型:Boolean|Object|Function
默認值:false
描述:允許覆蓋模板中使用的參數(shù)。
類型:Boolean|String
默認值:true
描述:true || 'head' || 'body' || false將所有資產(chǎn)注入到給定的模板或templateContent中。當(dāng)傳遞'body'時,所有javascript資源將被放置在body元素的底部。'head'將把腳本放置在head元素中。設(shè)置為true時,將根據(jù)scriptLoading選項,決定是把腳本添加到head還是body中。使用false禁用自動注入。
類型:String|'auto'
默認值:auto
描述:publicPath屬性值用于script和link 標簽。
類型:blocking|defer
默認值:defer
描述:現(xiàn)代瀏覽器支持非阻塞javascript加載(“defer”),以提高頁面啟動性能。
類型:String
默認值:空
描述:將給定的圖標路徑添加到輸出的HTML中。
類型:Object
默認值:{}
描述:允許注入meta標簽。例如:meta: {viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no'}。
類型:Object|String|false
默認值:false
描述:注入一個base標簽。如base:“https://example.com/path/page.html
類型:Boolean|Object
默認值:如果mode為'production'則為true,否則為false
描述:控制是否以及以何種方式壓縮輸出。
類型:Boolean
默認值:false
描述:如果為true,則附加一個唯一的webpack編譯哈希到所有包含的腳本和CSS文件。這對于緩存銷毀是很有用的
類型:Boolean
默認值:true
描述:只有當(dāng)文件被更改時,才會刪除它。
類型:Boolean
默認值:true
描述:錯誤的詳細信息將寫入HTML頁面。
類型:?
默認值:?
描述:只允許添加一些chunk(例如:只添加unit-test 的chunk)
類型:String|Function
默認值:auto
描述:允許控制塊在包含到HTML之前應(yīng)該如何排序。允許的值是'none' | 'auto' | 'manual' | {Function}。
類型:Array.<string>
默認值:空
描述:允許你跳過一些chunk(例如不添加unit-test 的chunk)。
類型:Boolean
默認值:false
描述:如果為true,則將link標簽呈現(xiàn)為自動關(guān)閉(XHTML兼容)
下面是一個webpack配置示例,演示了如何使用這些選項:
{
entry: 'index.js',
output: {
path: __dirname + '/dist',
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin({
title: 'My App',
filename: 'assets/admin.html'
})
]
}
要生成多個HTML文件,請在插件數(shù)組中多次聲明插件。
配置示例:
{
entry: 'index.js',
output: {
path: __dirname + '/dist',
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin(), // Generates default index.html
new HtmlWebpackPlugin({ // Also generate a test.html
filename: 'test.html',
template: 'src/assets/test.html'
})
]
}
如果默認生成的HTML不能滿足您的需要,您可以提供自己的模板。最簡單的方法是使用template選項并傳遞一個定制的HTML文件。html-webpack-plugin會自動將所有必需的CSS, JS, manifest和favicon文件注入到標記中。
配置文件的部分內(nèi)容:
plugins: [
new HtmlWebpackPlugin({
title: 'Custom template',
// Load a custom template (lodash by default)
template: 'index.html'
})
]
模板文件index.html的內(nèi)容:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
</body>
</html>
如果您已經(jīng)有一個模板加載器,您可以使用它來解析模板。請注意,如果您指定了html加載器并使用.html文件作為模板,也會發(fā)生這種情況。
module: {
loaders: [
{ test: /\.hbs$/, loader: "handlebars-loader" }
]
},
plugins: [
new HtmlWebpackPlugin({
title: 'Custom template using Handlebars',
template: 'index.hbs'
})
]
您可以使用現(xiàn)成的lodash語法。如果inject特性不適合你的需要,而你又想完全控制資產(chǎn)的位置,可以使用html-webpack-template項目的默認模板作為你自己編寫模板的起點。
程序開發(fā)過程中,我們始終要謹記的一點就是:程序是寫給人看的,不是寫給機器看的。任何項目開發(fā),都必須要考慮到人員迭代,我們不能讓下一個接手你代碼的人,在看到你寫的代碼時會說出這樣的話,“這個代碼是人寫出來的嗎?可讀性太差了”。因此,我們必須遵循一定的規(guī)范,讓代碼的可讀性更強。
今天,我們就一起來看下前端開發(fā)過程所能涉及到的跟HTML有關(guān)的規(guī)范問題。
HTML5
在HTML文件中,推薦使用支持HTML5特性的文檔聲明,<!DOCTYPE html>。
首先是在文件的命名上,應(yīng)當(dāng)采用駝峰式命名,首字母小寫,后面每個單詞首字母大寫,而且對于具體的文件應(yīng)當(dāng)具有語義化,能夠給人一種直觀的感受這個文件的作用是什么。現(xiàn)在前端開發(fā)開發(fā)過程中都講求模塊化開發(fā),甚至是組件化開發(fā),在文件命名時更應(yīng)該以模塊名或者組件名來命名。
例如在寫一個AngularJS應(yīng)用時,由于會涉及到Controller,Service,F(xiàn)ilter等概念,我們會分別建立一個文件,假如這個模塊的名字是庫存管理stockManage,我們可以這樣來命名文件。
stockManageCtrl
stockChangeService
stockChangeFilter
我們所說的語義化指的是使用具有語義化的標簽,在H5中添加了類似于header, nav, article, section, aside, footer等標簽,從單詞的意思上我們也很容易看出標簽的含義。
我們不推薦使用只有div標簽的頁面,例如
不推薦使用
而是應(yīng)該使用以下這種帶有語義化的標簽。
推薦使用
img標簽是網(wǎng)頁用來顯示照片的標簽,在頁面所有標簽中占據(jù)的比例非常之高,但是在使用img標簽時也有下面需要注意的點。
給定width和height屬性
因為瀏覽器在加載圖片的過程中,需要先下載圖片,然后再解析圖片的高度和寬度,如果不給img元素設(shè)定高度和寬度,這樣在圖片加載過程中會不斷的計算,重排頁面的布局,在網(wǎng)絡(luò)不好的時候就會經(jīng)常出現(xiàn)元素出現(xiàn)不規(guī)律移動的情況。因此給img元素設(shè)定width和height屬性是必要的。
alt屬性
img標簽的alt屬性表示的是在圖片無法顯示時,使用文字來代替顯示,它可以用在以下幾個場景中:
網(wǎng)路延遲太大
src屬性指定路徑出錯
瀏覽器禁用圖像
由于其有良好的信息提示效果,并且有助于網(wǎng)頁SEO效果,強烈建議在img標簽中使用alt屬性。
而且很重要的一點是img標簽的引入是需要呈現(xiàn)出與頁面相關(guān)的內(nèi)容,其他情況應(yīng)該使用CSS樣式實現(xiàn)。例如我們不推薦下面這種情況。
不推薦
而推薦使用下面這種情況
推薦使用
前端文件主要包括HTML頁面文件,CSS樣式文件和Javascript腳本文件。我們應(yīng)該讓三者各司其職,在HTML中不應(yīng)該出現(xiàn)CSS和JS表達式;在JS文件中,不應(yīng)該出現(xiàn)大量的HTML和CSS代碼。在HTML文檔中應(yīng)當(dāng)盡量少的引入CSS和JS文件。為了保證文件的純凈,我們應(yīng)當(dāng)遵循下面的原則。
一個HTML文件應(yīng)該只引入一個CSS文件
合理運用JS合并技術(shù)(Gulp, Webpack插件),保證引入JS文件不多于兩個
不使用行內(nèi)腳本元素(<script>alert('Hello World')</script>)
不在標簽上使用style內(nèi)聯(lián)樣式
不要使用style屬性
腳本加載在網(wǎng)頁加載過程中是一個很耗性能的過程,如果把JS文件放在head標簽里,它的加載會一直阻塞DOM的解析,造成頁面延遲。
因此現(xiàn)在講求的是腳本的異步加載過程,我們會使用到async關(guān)鍵字,考慮到瀏覽器的兼容性,我們推薦使用下面的方式加載腳本。
推薦方式
合理使用ID和錨點可以非常方便的實現(xiàn)當(dāng)前頁面間的跳轉(zhuǎn),現(xiàn)在越來越多的教程網(wǎng)頁由于是單頁面,經(jīng)常會用到錨點跳轉(zhuǎn)。
對錨點知識還不了解的,可以看看我寫的這篇文章《神奇的html錨點,讓你的網(wǎng)頁在內(nèi)部自由的跳轉(zhuǎn)》。
今天這篇文章主要總結(jié)了前端開發(fā)過程中的HTML規(guī)范問題,相信大家也或多或少遇到過,希望這篇文章能加深大家的認識。
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。