简易富文本编辑
让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小时内与您取得联系。