簡易富文本編輯
讓HTML標簽的contenteditable屬性設為true即可直接修改內部內容,但是Android和在pc網頁上使用可能存在差異。這里分享一個簡單的富文本編輯,需要配合Android使用。
這個富文本編輯目前通過于Android端交互可以向其中添加圖片、添加超鏈接、普通文本。主要靠js驅動(我的基礎不行,只能寫成這樣)。詳細解釋看代碼即可,需要配合Android知識。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>富文本編輯</title>
<script type="text/javascript">
/*每一個被添加的標簽(也就是圖片、超鏈接)都會被一層div包裹,固定其具體位置,并且每次添加完一個都會在其下部添加一個div用于輸入文本(可忽略)*/
/*添加外層標簽*/
function outDiv(inLabel)
{
var outdiv=document.createElement("div");
outdiv.style.textAlign="center";
outdiv.contentEditable=true;
outdiv.appendChild(inLabel);
document.getElementById("main").appendChild(outdiv);
var nextDiv=document.createElement("div");
document.getElementById("main").appendChild(nextDiv);
nextDiv.outerHTML="<div style='margin-left: 30px; margin-right: 30px;' contenteditable='true'><br></div>"
}
/*添加圖片*/
function addPhoto(path)
{
var addImg=document.createElement("img");
outDiv(addImg);
addImg.outerHTML="<img src='" + path + "' alt='圖片存在問題' id='" + path + "'/>";
}
/*Android端存在圖片傳輸問題,是先將圖片保存到文件夾內,再在html中調用,而在html中使用退格鍵即可刪除標簽,所以Android端在適當的時候清除沒有用到的圖片*/
/*確定圖片是否存在于html頁面中*/
function isExistedPhoto(id)
{
if(document.getElementById(id))
{
return 1;
}
else
{
return 0;
}
}
/*受Android端影響,啟用預覽模式時,將整體網頁所有標簽設為不可編輯(代碼在下面),同時為了確保同步,每次預覽都會在Android端存儲,因為js沒法直接存儲文件,所以將網頁代碼整體返回到Android端接收并保存到文件內,注意Android端應對得到的結果轉碼,因為得到的是unicode碼,即使js已經轉過了。*/
/*返回整體網頁*/
function wholeHtml()
{
return unescape(document.getElementsByTagName('html')[0].outerHTML.toString());
}
/*添加鏈接*/
function addHref(href)
{
var a=document.createElement("a");
a.href=href;
a.innerText=href;
a.contentEditable=true;
outDiv(a);
}
/*開啟預覽模式則不可編輯,此時可以驗證鏈接*/
/*可編輯設置*/
function setEditAble(type)
{
if(!type)
{
getEdit("div", type);
getEdit("img", type);
getEdit("a", type);
}
else
{
getEdit("div", type);
getEdit("img", type);
getEdit("a", type);
}
}
/*獲取對象*/
function getEdit(label, type)
{
var aa=document.getElementsByTagName(label);
if(!type)
{
for( var a1=0; a1 < aa.length; a1++)
{
aa[a1].contentEditable=false;
}
}
else
{
for( var a1=0; a1 < aa.length; a1++)
{
aa[a1].contentEditable=true;
}
}
}
</script>
</head>
<body>
<!--只要一個基礎div就行,甚至可以直接用body添加id代替-->
<div id="main" contenteditable="true" style="margin-left: 30px; margin-right: 30px;"></div>
</body>
</html>
由于本人技術能力限制,無法很好的寫出代碼,只能提供一個簡易的編輯。
對應Android端的簡易介紹
Android端根據js代碼設置對應內容。
webview建立
//根據id查找
webView=rootView.findViewById(R.id.makeArticle);
//啟用js支持
webView.getSettings().setJavaScriptEnabled(true);
//下面有一堆設置內容,我也不太明白,大致是啟用js支持、支持網絡傳輸、支持html5格式存儲、支持本地存儲 webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
//網頁處理,內部可根據網頁開始、網頁完成等狀態做處響應
webClient=new WebClient();
webView.setWebViewClient(webClient);
//允許操作文件
webView.getSettings().setAllowFileAccessFromFileURLs(true);
webView.getSettings().setAllowFileAccess(true);
webView.getSettings().setAllowUniversalAccessFromFileURLs(true);
webView.getSettings().setBlockNetworkLoads(false);
webView.getSettings().setBlockNetworkImage(false);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setDatabaseEnabled(true);
//添加js可調用的函數類,函數使用javascriptinterface注釋,內部函數可以被js所調用
webView.addJavascriptInterface(new MakeArticleWeb(getContext(), username, articleId, webView), "makeArticle");
使用Android調用js代碼
//webview使用要在同一進程中
//基礎格式
webView.loadUrl(url);//注意此調用異步加載,可能比后續loadUrl方法加載慢
//加載js代碼
webView.loadUrl("javascript:js函數(參數)");//傳入一個字符串,前面javascript固定,后面為要調用的函數名,注意當參數要傳入字符串時,加上單引號。
//loaddata
webView.loadData(文本,文本格式(mimetype)(例如text/html為html文本),編碼格式(例如UTF-8));
WebView的loadUrl異步加載問題
因loadUrl加載順序不一致導致錯誤,因為webview使用必須在統一進程中,最好避免。如果實在需要,可以通過WebViewCilent中onPageFinsihed方法,在其中運行js可避免頁面未完全加載導致js無法執行的異常。
示例:
//網頁監控
public class WebClient extends WebViewClient
{
//頁面加載完成調用該方法
@Override
public void onPageFinished(WebView view, String url)
{
super.onPageFinished(view, url);
onCreateViewUpdate();
//不為空,更新數據
if(addList.size() > 0 && number <=30)
{
for (Bitmap value : addList.values()) {
String savePath=MakeUUID.makeUUID(username + "-" + articleId) + ".png";
saveThePhotoWithBitmap(value, savePath);
//此處調用了js,而且該js必須在頁面完全加載后才能有效使用
webView.loadUrl(addTo(savePath, 0));
}
}
//保存網頁數據
saveHtml();
}
webview調用goback方法返回亂七八糟的東西(例如返回url)
單擊webview中超鏈接進入其它網頁再調用goback返回時可能出現問題,可通過修改默認的gobakc返回流程改善。
代碼:
public String startUrl=thePath;//記錄一開始的url,直接通過內部類寫死,或在構造方法中定義
private int pageNumber=0;//頁面計數,判斷當前網頁是不是主網頁
//重寫該方法,適配Android高版本
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
{
System.out.println(startUrl);
//如果頁面不是主頁面且當前url不是一開始的url,跳轉會主界面
if(!request.getUrl().equals(startUrl) && pageNumber !=0)
{
System.out.println(pageNumber);
pageNumber=0;
view.loadUrl(startUrl);//返回主界面
return true;
}
else
{
pageNumber=1;
//使用原流程
return super.shouldOverrideUrlLoading(view, request);
}
}
最好把這些代碼寫在內部類中方便調用。
NSI(Windows-1252)
ANSI 是 Windows 95 及其之前的 Windows 系統中默認的字符集。
ANSI 也稱為 Windows-1252。
重要提示
ANSI 和 ISO-8859-1 非常相似,唯一的不同是在 32 個字符上。
在 ANSI 中,從 128 到 159 的字符用于一些有用的字符,比如歐元符號。
在 ISO-8859-1 中,這些字符映射為在 HTML 中不起作用的控制字符。
許多 Web 開發者聲明 ISO-8859-1,并使用這 32 個值,就像它們使用的是 Windows-1252。
由于這種常見的誤解,當 ISO-8859-1 被聲明時,瀏覽器將更改為 Windows-1252。這對以下文檔類型都適用:HTML4、HTML5 和 XHTML。
ANSI 和 ASCII
ANSI 的第一部分(實體編號 0-127)是原來的 ASCII 字符集。它包含數字、大小寫英文字母和一些特殊字符。
如需深入了解 ASCII,請查看完整的 ASCII 參考手冊。
ANSI 字符集
字符 | 編號 | 實體名稱 | 描述 |
---|---|---|---|
32 | 空格(space) | ||
! | 33 | 感嘆號(exclamation mark) | |
" | 34 | " | 引號(quotation mark) |
# | 35 | 數字符號(number sign) | |
$ | 36 | 美元符號(dollar sign) | |
% | 37 | 百分比符號(percent sign) | |
& | 38 | & | & 符號(ampersand) |
' | 39 | 撇號(apostrophe) | |
( | 40 | 左括號(left parenthesis) | |
) | 41 | 右括號(right parenthesis) | |
* | 42 | 星號(asterisk) | |
+ | 43 | 加號(plus sign) | |
, | 44 | 逗號(comma) | |
- | 45 | 連字符(hyphen-minus) | |
. | 46 | 句號(full stop) | |
/ | 47 | 斜線(solidus) | |
0 | 48 | 數字 0(digit zero) | |
1 | 49 | 數字 1(digit one) | |
2 | 50 | 數字 2(digit two) | |
3 | 51 | 數字 3(digit three) | |
4 | 52 | 數字 4(digit four) | |
5 | 53 | 數字 5(digit five) | |
6 | 54 | 數字 6(digit six) | |
7 | 55 | 數字 7(digit seven) | |
8 | 56 | 數字 8(digit eight) | |
9 | 57 | 數字 9(digit nine) | |
: | 58 | 冒號(colon) | |
; | 59 | 分號(semicolon) | |
< | 60 | < | 小于號(less-than sign) |
= | 61 | 等于號(equals sign) | |
> | 62 | > | 大于號(greater-than sign) |
? | 63 | 問號(question mark) | |
@ | 64 | @ 符號(commercial at) | |
A | 65 | 拉丁文大寫字母 A | |
B | 66 | 拉丁文大寫字母 B | |
C | 67 | 拉丁文大寫字母 C | |
D | 68 | 拉丁文大寫字母 D | |
E | 69 | 拉丁文大寫字母 E | |
F | 70 | 拉丁文大寫字母 F | |
G | 71 | 拉丁文大寫字母 G | |
H | 72 | 拉丁文大寫字母 H | |
I | 73 | 拉丁文大寫字母 I | |
J | 74 | 拉丁文大寫字母 J | |
K | 75 | 拉丁文大寫字母 K | |
L | 76 | 拉丁文大寫字母 L | |
M | 77 | 拉丁文大寫字母 M | |
N | 78 | 拉丁文大寫字母 N | |
O | 79 | 拉丁文大寫字母 O | |
P | 80 | 拉丁文大寫字母 P | |
Q | 81 | 拉丁文大寫字母 Q | |
R | 82 | 拉丁文大寫字母 R | |
S | 83 | 拉丁文大寫字母 S | |
T | 84 | 拉丁文大寫字母 T | |
U | 85 | 拉丁文大寫字母 U | |
V | 86 | 拉丁文大寫字母 V | |
W | 87 | 拉丁文大寫字母 W | |
X | 88 | 拉丁文大寫字母 X | |
Y | 89 | 拉丁文大寫字母 Y | |
Z | 90 | 拉丁文大寫字母 Z | |
[ | 91 | 左方括號(left square bracket) | |
\ | 92 | 反斜線(reverse solidus) | |
] | 93 | 右方括號(right square bracket) | |
^ | 94 | 插入符號(circumflex accent) | |
_ | 95 | 下劃線(low line) | |
` | 96 | 重音符(grave accent) | |
a | 97 | 拉丁文小寫字母 a | |
b | 98 | 拉丁文小寫字母 b | |
c | 99 | 拉丁文小寫字母 c | |
d | 100 | 拉丁文小寫字母 d | |
e | 101 | 拉丁文小寫字母 e | |
f | 102 | 拉丁文小寫字母 f | |
g | 103 | 拉丁文小寫字母 g | |
h | 104 | 拉丁文小寫字母 h | |
i | 105 | 拉丁文小寫字母 i | |
j | 106 | 拉丁文小寫字母 j | |
k | 107 | 拉丁文小寫字母 k | |
l | 108 | 拉丁文小寫字母 l | |
m | 109 | 拉丁文小寫字母 m | |
n | 110 | 拉丁文小寫字母 n | |
o | 111 | 拉丁文小寫字母 o | |
p | 112 | 拉丁文小寫字母 p | |
q | 113 | 拉丁文小寫字母 q | |
r | 114 | 拉丁文小寫字母 r | |
s | 115 | 拉丁文小寫字母 s | |
t | 116 | 拉丁文小寫字母 t | |
u | 117 | 拉丁文小寫字母 u | |
v | 118 | 拉丁文小寫字母 v | |
w | 119 | 拉丁文小寫字母 w | |
x | 120 | 拉丁文小寫字母 x | |
y | 121 | 拉丁文小寫字母 y | |
z | 122 | 拉丁文小寫字母 z | |
{ | 123 | 左花括號(left curly bracket) | |
| | 124 | 豎線(vertical line) | |
} | 125 | 右花括號(right curly bracket) | |
~ | 126 | 波浪線(tilde) | |
127 | 未使用(NOT USED) | ||
| 128 | € | 歐元符號(euro sign) |
129 | 未使用(NOT USED) | ||
? | 130 | ‚ | 下單引號(single low-9 quotation mark) |
? | 131 | ƒ | 帶鉤的拉丁文小寫字母 f |
? | 132 | „ | 下雙引號(double low-9 quotation mark) |
… | 133 | … | 水平省略號(horizontal ellipsis) |
? | 134 | † | 劍號(dagger) |
? | 135 | ‡ | 雙劍號(double dagger) |
? | 136 | ˆ | 修飾字母抑揚音(modifier letter circumflex accent) |
‰ | 137 | ‰ | 千分比符號(per mille sign) |
? | 138 | Š | 帶有 caron 的拉丁文大寫字母 S |
? | 139 | ‹ | 左單角引號(single left-pointing angle quotation mark) |
? | 140 | Œ | 拉丁文大寫連字 OE |
141 | 未使用(NOT USED) | ||
? | 142 | Ž | 帶有 caron 的拉丁文大寫字母 Z |
143 | 未使用(NOT USED) | ||
144 | 未使用(NOT USED) | ||
' | 145 | ‘ | 左單引號(left single quotation mark) |
' | 146 | ’ | 右單引號(right single quotation mark) |
" | 147 | “ | 左雙引號(left double quotation mark) |
" | 148 | ” | 右雙引號(right double quotation mark) |
? | 149 | • | 著重號(bullet) |
– | 150 | – | 短破折號/連字符(en dash) |
— | 151 | — | 長破折號(em dash) |
? | 152 | ˜ | 小波浪線(small tilde) |
? | 153 | ™ | 貿易標記符號(trade mark sign) |
? | 154 | š | 帶有 caron 的拉丁文小寫字母 s |
? | 155 | › | 右單角引號(single right-pointing angle quotation mark) |
? | 156 | œ | 拉丁文小寫連字 oe |
157 | 未使用(NOT USED) | ||
? | 158 | ž | 帶有 caron 的拉丁文小寫字母 z |
? | 159 | Ÿ | 帶有分音符(diaeresis)的拉丁文大寫字母 Y |
160 | | 不換行空格(no-break space) | |
? | 161 | ¡ | 倒置感嘆號(inverted exclamation mark) |
¢ | 162 | ¢ | 美分符號(cent sign) |
£ | 163 | £ | 英鎊符號(pound sign) |
¤ | 164 | ¤ | 貨幣符號(currency sign) |
¥ | 165 | ¥ | 日元符號(yen sign) |
| | 166 | ¦ | 間斷的豎杠(broken bar) |
§ | 167 | § | 小節號(section sign) |
¨ | 168 | ¨ | 分音符號(diaeresis) |
? | 169 | © | 版權所有(copyright sign) |
a | 170 | ª | 陰性序數記號(feminine ordinal indicator) |
? | 171 | « | 左雙角引號(left-pointing double angle quotation mark) |
? | 172 | ¬ | 否定符號(not sign) |
173 | ­ | 軟連字符(soft hyphen) | |
? | 174 | ® | 注冊商標(registered sign) |
ˉ | 175 | ¯ | 長音符號(macron) |
° | 176 | ° | 度符號(degree sign) |
± | 177 | ± | 加減號/正負號(plus-minus sign) |
2 | 178 | ² | 上標 2(superscript two) |
3 | 179 | ³ | 上標 3(superscript three) |
′ | 180 | ´ | 尖音符號(acute accent) |
μ | 181 | µ | 微米符號(micro sign) |
? | 182 | ¶ | 段落符號(pilcrow sign) |
· | 183 | · | 中間點(middle dot) |
? | 184 | ¸ | 變音符號(cedilla) |
1 | 185 | ¹ | 上標 1(superscript one) |
o | 186 | º | 陽性序數記號(masculine ordinal indicator) |
? | 187 | » | 右雙角引號(right-pointing double angle quotation mark) |
? | 188 | ¼ | 1/4 分數(vulgar fraction one quarter) |
? | 189 | ½ | 1/2 分數(vulgar fraction one half) |
? | 190 | ¾ | 3/4 分數(vulgar fraction three quarters) |
? | 191 | ¿ | 倒置問號(inverted question mark) |
à | 192 | À | 帶有重音符號(grave)的拉丁文大寫字母 A |
á | 193 | Á | 帶有尖音符號(acute)的拉丁文大寫字母 A |
? | 194 | Â | 帶有抑揚音符號(circumflex)的拉丁文大寫字母 A |
? | 195 | Ã | 帶有波浪線的拉丁文大寫字母 A |
? | 196 | Ä | 帶有分音符(diaeresis)的拉丁文大寫字母 A |
? | 197 | Å | 帶有上圓圈的拉丁文大寫字母 A |
? | 198 | Æ | 拉丁文大寫字母 AE |
? | 199 | Ç | 帶有變音符號(cedilla)的拉丁文大寫字母 C |
è | 200 | È | 帶有重音符號(grave)的拉丁文大寫字母 E |
é | 201 | É | 帶有尖音符號(acute)的拉丁文大寫字母 E |
ê | 202 | Ê | 帶有抑揚符號(circumflex)的拉丁文大寫字母 E |
? | 203 | Ë | 帶有分音符(diaeresis)的拉丁文大寫字母 E |
ì | 204 | Ì | 帶有重音符號(grave)的拉丁文大寫字母 I |
í | 205 | Í | 帶有尖音符號(acute)的拉丁文大寫字母 I |
? | 206 | Î | 帶有抑揚音符號(circumflex)的拉丁文大寫字母 I |
? | 207 | Ï | 帶有分音符(diaeresis)的拉丁文大寫字母 I |
D | 208 | Ð | 拉丁文大寫字母 Eth |
? | 209 | Ñ | 帶有波浪線的拉丁文大寫字母 N |
ò | 210 | Ò | 帶有重音符號(grave)的拉丁文大寫字母 O |
ó | 211 | Ó | 帶有尖音符號(acute)的拉丁文大寫字母 O |
? | 212 | Ô | 帶有抑揚音符號(circumflex)的拉丁文大寫字母 O |
? | 213 | Õ | 帶有波浪線的拉丁文大寫字母 O |
? | 214 | Ö | 帶有分音符(diaeresis)的拉丁文大寫字母 O |
× | 215 | × | 乘號(multiplication sign) |
? | 216 | Ø | 帶有刪除線的拉丁文大寫字母 O |
ù | 217 | Ù | 帶有重音符號(grave)的拉丁文大寫字母 U |
ú | 218 | Ú | 帶有尖音符號(acute)的拉丁文大寫字母 U |
? | 219 | Û | 帶有抑揚音符號(circumflex)的拉丁文大寫字母 U |
ü | 220 | Ü | 帶有分音符(diaeresis)的拉丁文大寫字母 U |
Y | 221 | Ý | 帶有尖音符號(acute)的拉丁文大寫字母 Y |
T | 222 | Þ | 拉丁文大寫字母 Thorn |
? | 223 | ß | 拉丁文小寫字母 sharp s |
à | 224 | à | 帶有重音符號(grave)的拉丁文小寫字母 a |
á | 225 | á | 帶有尖音符號(acute)的拉丁文小寫字母 a |
a | 226 | â | 帶有抑揚音符號(circumflex)的拉丁文小寫字母 a |
? | 227 | ã | 帶有波浪線的拉丁文小寫字母 a |
? | 228 | ä | 帶有分音符(diaeresis)的拉丁文小寫字母 a |
? | 229 | å | 帶有上圓圈的拉丁文小寫字母 a |
? | 230 | æ | 拉丁文小寫字母 ae |
? | 231 | ç | 帶有變音符號(cedilla)的拉丁文小寫字母 c |
è | 232 | è | 帶有重音符號(grave)的拉丁文小寫字母 e |
é | 233 | é | 帶有尖音符號(acute)的拉丁文小寫字母 e |
ê | 234 | ê | 帶有抑揚音符號(circumflex)的拉丁文小寫字母 e |
? | 235 | ë | 帶有分音符(diaeresis)的拉丁文小寫字母 e |
ì | 236 | ì | 帶有重音符號(grave)的拉丁文小寫字母 i |
í | 237 | í | 帶有尖音符號(acute)的拉丁文小寫字母 i |
? | 238 | î | 帶有抑揚音符號(circumflex)的拉丁文小寫字母 i |
? | 239 | ï | 帶有分音符(diaeresis)的拉丁文小寫字母 i |
e | 240 | ð | 拉丁文小寫字母 eth |
? | 241 | ñ | 帶有波浪線的拉丁文小寫字母 n |
ò | 242 | ò | 帶有重音符號(grave)的拉丁文小寫字母 o |
ó | 243 | ó | 帶有尖音符號(acute)的拉丁文小寫字母 o |
? | 244 | ô | 帶有抑揚音符號(circumflex)的拉丁文小寫字母 o |
? | 245 | õ | 帶有波浪線的拉丁文小寫字母 o |
? | 246 | ö | 帶有分音符(diaeresis)的拉丁文小寫字母 o |
÷ | 247 | ÷ | 除號(division sign) |
? | 248 | ø | 帶有刪除線的拉丁文小寫字母 o |
ù | 249 | ù | 帶有重音符號(grave)的拉丁文小寫字母 u |
ú | 250 | ú | 帶有尖音符號(acute)的拉丁文小寫字母 u |
? | 251 | û | 帶有抑揚音符號(circumflex)的拉丁文小寫字母 u |
ü | 252 | ü | 帶有分音符(diaeresis)的拉丁文小寫字母 u |
y | 253 | ý | 帶有尖音符號(acute)的拉丁文小寫字母 y |
t | 254 | þ | 拉丁文小寫字母 thorn |
? | 255 | ÿ | 帶有分音符(diaeresis)的拉丁文小寫字母 y |
ANSI 控制字符
ANSI 控制字符(00-31,加上 127)最初被設計用來控制諸如打印機和磁帶驅動器之類的硬件設備。
控制字符(除了水平制表符、換行、回車之外)在 HTML 文檔中不起任何作用。
字符 | 編號 | 描述 |
---|---|---|
NUL | 00 | 空字符(null character) |
SOH | 01 | 標題開始(start of header) |
STX | 02 | 正文開始(start of text) |
ETX | 03 | 正文結束(end of text) |
EOT | 04 | 傳輸結束(end of transmission) |
ENQ | 05 | 請求(enquiry) |
ACK | 06 | 收到通知/響應(acknowledge) |
BEL | 07 | 響鈴(bell) |
BS | 08 | 退格(backspace) |
HT | 09 | 水平制表符(horizontal tab) |
LF | 10 | 換行(line feed) |
VT | 11 | 垂直制表符(vertical tab) |
FF | 12 | 換頁(form feed) |
CR | 13 | 回車(carriage return) |
SO | 14 | 不用切換(shift out) |
SI | 15 | 啟用切換(shift in) |
DLE | 16 | 數據鏈路轉義(data link escape) |
DC1 | 17 | 設備控制 1(device control 1) |
DC2 | 18 | 設備控制 2(device control 2) |
DC3 | 19 | 設備控制 3(device control 3) |
DC4 | 20 | 設備控制 4(device control 4) |
NAK | 21 | 拒絕接收/無響應(negative acknowledge) |
SYN | 22 | 同步空閑(synchronize) |
ETB | 23 | 傳輸塊結束(end transmission block) |
CAN | 24 | 取消(cancel) |
EM | 25 | 已到介質末端/介質存儲已滿(end of medium) |
SUB | 26 | 替補/替換(substitute) |
ESC | 27 | 溢出/逃離/取消(escape) |
FS | 28 | 文件分隔符(file separator) |
GS | 29 | 組分隔符(group separator) |
RS | 30 | 記錄分隔符(record separator) |
US | 31 | 單元分隔符(unit separator) |
DEL | 127 | 刪除(delete) |
如您還有不明白的可以在下面與我留言或是與我探討QQ群308855039,我們一起飛!
節課我們講了關于事件的基本知識,主要包括事件對象和它的一些應用。從這節課開始我們學習2個更加高級的知識。
默認行為
當我們打開一個空白頁面的時候,右鍵點擊頁面會彈出來一個菜單——當然,實際上我們從來沒有通過JS寫過這么一個菜單,而是瀏覽器自帶的功能。這種瀏覽器本身自己帶的功能和事件我們將它稱之為默認行為。
在這之前,要為大家介紹一個新的事件——oncontextmenu,代表的就是當用戶點擊右鍵呼出菜單的事件。現在我們用oncontextmenu來做一些事情。值得一提的是,oncontextmenu是可以有返回值的,如果我們return一個false的話會發生什么呢?
<html> <head> <meta charset="utf-8" /> <title>無標題文檔</title> <script>document.oncontextmenu=function (){ return false; //阻止默認事件};</script> </head> <body> </body> </html>
大家可以自己嘗試一下,如果我們return一個false值回去的話,右鍵菜單將會被阻止彈出。在系統默認事件中return false的話可以有效地阻止該默認事件。
當然,阻止右鍵菜單并不是我們最終的目的,我們最終的目的是為了能彈出自定義右鍵菜單,我們現在來看一下,如何在屏蔽右鍵菜單的基礎之上,再彈出一個自己的菜單。
<html> <head> <meta charset="utf-8" /> <title>無標題文檔</title> <style> * {margin:0; padding:0; list-style:none;} #div1 {position:absolute; width:80px; background:#CCC; border:1px solid black; display:none;} </style> <script> document.oncontextmenu=function (ev) { var oEvent=ev||event; var oDiv=document.getElementById('div1'); oDiv.style.display='block'; oDiv.style.left=oEvent.clientX+'px'; oDiv.style.top=oEvent.clientY+'px'; return false; }; document.onclick=function () { var oDiv=document.getElementById('div1'); oDiv.style.display='none'; }; </script> </head> <body> <div id="div1"> <ul> <li>aaa</li> <li>bbb</li> <li>ccc</li> <li>ddd</li> </ul> </div> </body> </html>
效果如下:
這個程序里面,我們除了用return false阻止了默認的系統菜單外,還自定義了一個div,其位置為鼠標點擊的位置,同時添加了一個點擊頁面其他位置時,div消失的效果——這樣就完成了一個自定義右鍵菜單。
到目前為止,我們學習了一下阻止默認行為最簡單的一種應用。現在我們再來看一個默認行為的另一種應用——大家平時在表單里面會經常需要用戶去填一些用戶名,密碼,郵箱,qq號等信息。當我們輸入qq號時,我們希望用戶只能輸入數字,而不能輸入字母和符號,這應該怎么做到呢?這里我們需要使用上節課提過的onkeydown事件。
<html> <head> <meta charset="utf-8" /> <title>無標題文檔</title> <script>window.onload=function (){ var oTxt=document.getElementById('txt1'); oTxt.onkeydown=function () { var oEvent=ev||event; //alert(oEvent.keyCode); //0- 48 //9- 57 //如果 用戶按的 不是退格 并且 也不是數字if(oEvent.keyCode!=8 && (oEvent.keyCode<48 || oEvent.keyCode>57)) { return false; } }; }; </script> </head> <body> <input type="text" id="txt1" /> </body> </html>
值得一提的是,如果我們將onkeydown的return值也設為false的話,我們將無法在頁面用鍵盤進行任何輸入——實際上鍵盤輸入本身也是系統的一個默認行為,因此可以用return false將它阻止掉。所以其實這個程序的邏輯很簡單——通過keyCode判斷輸入的字符是否為數字,如果不是數字的話,return false阻止其輸入即可(注意不要把keyCode為8的退格鍵阻止掉)。實際上來說默認行為的各種應用是非常廣的,我們這里只舉了兩個例子,其他的大家可以自己去發掘。
拖拽
拖拽的含義大家應該都明白,這里我們先從它的原理開始說起。首先我們先來看一個簡單的布局:
<html> <head> <meta charset="utf-8" /> <title>無標題文檔</title> <style>#div1 {width:200px; height:200px; background:red; position:absolute;}</style> <script> window.onload=function () { var oDiv=document.getElementById('div1'); var disX=0; var disY=0; oDiv.onmousedown=function (ev) { var oEvent=ev||event; disX=oEvent.clientX-oDiv.offsetLeft; disY=oEvent.clientY-oDiv.offsetTop; document.onmousemove=function (ev) { var oEvent=ev||event; oDiv.style.left=oEvent.clientX-disX+'px'; oDiv.style.top=oEvent.clientY-disY+'px'; }; document.onmouseup=function () { document.onmousemove=null; document.onmouseup=null; }; return false; //這里是為了阻止火狐瀏覽器的一個小bug。 }; }; </script> </head> <body> <div id="div1"></div> </body> </html>
大家隨便在電腦上拖拽一個東西就可以發現,拖拽的一個性質是:在拖拽時,鼠標和元素右上角的距離是保持不變的。距離的求法也很簡單:用鼠標的位置減去元素右上角的位置即可。
然后對于拖拽來說,大家可以很容易聯想到它涉及到的幾個JS事件:鼠標按下,鼠標移動和鼠標抬起。通過這些東西的組合,我們就可以輕松寫出一個拖拽了(注意1.onmousemove事件需要添加為在onmousedown事件觸發后才會被觸發的事件2.onmousemove和onmouseup是添加給document而不是div1的事件,原因在于防止鼠標移出div或屏幕)。
效果如下:
現在我們就擁有了一個沒有任何bug的拖拽,但雖然沒有程序上的bug,但是有一些用戶體驗不太好的地方,比如,當用戶將拖拽框拖出屏幕后可能就找不到拖拽框了。現在我們要嘗試解決這個問題:
<html> <head> <meta charset="utf-8" /> <title>無標題文檔</title> <style> #div1 {width:200px; height:200px; background:red; position:absolute;} </style> <script> window.onload=function () { var oDiv=document.getElementById('div1'); var disX=0; var disY=0; oDiv.onmousedown=function (ev) { var oEvent=ev||event; disX=oEvent.clientX-oDiv.offsetLeft; disY=oEvent.clientY-oDiv.offsetTop; document.onmousemove=function (ev) { var oEvent=ev||event; var l=oEvent.clientX-disX; var t=oEvent.clientY-disY; if(l<0) { l=0; } else if(l>document.documentElement.clientWidth-oDiv.offsetWidth) { l=document.documentElement.clientWidth-oDiv.offsetWidth; } if(t<0) { t=0; } else if(t>document.documentElement.clientHeight-oDiv.offsetHeight) { t=document.documentElement.clientHeight-oDiv.offsetHeight; } oDiv.style.left=l+'px'; oDiv.style.top=t+'px'; }; document.onmouseup=function () { document.onmousemove=null; document.onmouseup=null; }; return false; }; };</script> </head> <body> <div id="div1"></div> </body> </html>
我們用l和t來儲存div的位置,當二者小于0的時候,將其變為0;當二者大于可視區寬高-元素本身寬高的時候,將其變為可視區寬高-元素本身寬高。這樣就完成了一個完美的拖拽。
以上,我們就把拖拽常一些問題簡單的講解一下,后面我們還會針對拖拽做更多的應用。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。