有没有什么视频软件可以免费看在腾讯和优酷土豆视频下载软件需要会员的剧

about-us.css
animate.css
bootstrap-fileupload.css
bootstrap-modal.css
bootstrap-responsive.min.css
bootstrap-responsive1.min.css
bootstrap-tag.css
bootstrap-toggle-buttons.css
bootstrap-tree.css
bootstrap-wysihtml5.css
bootstrap.min.css
chosen.css
clockface.css
colorpicker.css
coming-soon.css
datepicker.css
daterangepicker.css
datetimepicker.css
default.css
dropzone.css
DT_bootstrap.css
font-awesome.css
font-awesome.min.css
fullcalendar.css
glyphicons.css
halflings.css
invoice.css
jquery-ui-1.10.1.custom.min.css
jquery.easy-pie-chart.css
jquery.fancybox.css
jquery.fileupload-ui.css
jquery.gritter.css
jquery.nestable.css
jquery.tagsinput.css
jquery.ui.slider.css
jqvmap.css
login-soft.css
multi-select-metro.css
pricing-tables.css
profile.css
purple.css
search.css
select2_metro.css
style-metro.css
style-non-responsive.css
style-responsive.css
timeline.css
timepicker.css
uniform.default.css
animated-overlay.gif
avatar.png
bg-input-focus.png
bg-input.png
bstree-halflings.png
chosen-sprite.png
datatable-row-openclose.png
fancybox_loading.gif
fancybox_overlay.png
fancybox_sprite.png
fontawesome-webfont.eot
fontawesome-webfont.ttf
fontawesome-webfont.woff
glyphicons-halflings-white.png
glyphicons-halflings.png
glyphicons-regular.eot
glyphicons-regular.ttf
glyphicons-regular.woff
glyphicons-white.png
glyphicons.png
glyphiconshalflings-regular.eot
glyphiconshalflings-regular.ttf
glyphiconshalflings-regular.woff
glyphicons_halflings-white.png
glyphicons_halflings.png
hor-menu-search-close-white.png
hor-menu-search-close.png
hor-menu-search.png
icon-color-close.png
icon-color.png
ie-spacer.gif
loading.gif
logo-big.png
menu-toggler.png
overlay-icon.png
portlet-collapse-icon-white.png
portlet-collapse-icon.png
portlet-config-icon-white.png
portlet-config-icon.png
portlet-expand-icon-white.png
portlet-expand-icon.png
portlet-reload-icon-white.png
portlet-reload-icon.png
portlet-remove-icon-white.png
portlet-remove-icon.png
remove-icon-small.png
saturation.png
search-icon.png
select2-spinner.gif
select2.png
select2x2.png
sidebar-menu-arrow.png
sidebar-search-close.png
sidebar-toggler.jpg
sort_asc.png
sort_both.png
sort_desc.png
sprite.png
switch.png
syncfusion-icons-white.png
syncfusion-icons.png
ui-bg_flat_10_x100.png
ui-bg_glass_100_f6f6f6_1x400.png
ui-bg_glass_100_fdf5ce_1x400.png
ui-bg_glass_65_ffffff_1x400.png
ui-bg_highlight-soft_100_eeeeee_1x100.png
ui-bg_highlight-soft_75_ffe45c_1x100.png
ui-icons_x240.png
ui-icons_x240.png
ui-icons_ffffff_256x240.png
bootstrap-rtl.min.js
excanvas.js
jquery-1.8.3.min.js
respond.js
SEAWEBSITE_.sql
backgroundsize.min.htc
dark-bl.svg
dark-br.svg
dark-tl.svg
dark-tr.svg
light-bl.svg
light-br.svg
light-tl.svg
light-tr.svg
overlay.png
style-mobile.css
style-narrow.css
style-narrower.css
style-normal.css
style-noscript.css
style-wide.css
anchor.html
attachment
fileTypeImages
icon_chm.gif
icon_default.png
icon_doc.gif
icon_exe.gif
icon_jpg.gif
icon_mp3.gif
icon_mv.gif
icon_pdf.gif
icon_ppt.gif
icon_psd.gif
icon_rar.gif
icon_txt.gif
icon_xls.gif
alignicon.gif
alignicon.png
file-icons.gif
file-icons.png
progress.png
success.gif
success.png
attachment.css
attachment.html
background
success.png
background.css
background.html
charts0.png
charts1.png
charts2.png
charts3.png
charts4.png
charts5.png
charts.css
charts.html
jxface2.gif
neweditor-tab-bg.png
emotion.css
emotion.html
alignicon.jpg
progress.png
success.gif
success.png
image.html
insertframe
insertframe.html
music.html
preview.html
addimg.png
delimg.png
delimgH.png
emptyH.png
eraser.png
scaleH.png
scrawl.css
scrawl.html
searchreplace
searchreplace.html
snapscreen
snapscreen.html
spechars.html
dragicon.png
edittable.css
edittable.html
edittd.html
edittip.html
template.css
template.html
center_focus.jpg
file-icons.gif
file-icons.png
left_focus.jpg
none_focus.jpg
progress.png
right_focus.jpg
success.gif
success.png
video.html
webapp.html
fClipboard_ueditor.swf
imageUploader.swf
wordimage.html
addimage.png
alldeletebtnhoverskin.png
alldeletebtnupskin.png
background.png
button.png
deletedisable.png
deleteenable.png
listbackground.png
localimage.png
rotateleftdisable.png
rotateleftenable.png
rotaterightdisable.png
rotaterightenable.png
upload.png
localimage.png
upload.png
config.json
ueditor.css
ueditor.min.css
anchor.gif
arrow_down.png
arrow_up.png
button-bg.gif
cancelbutton.gif
charts.png
cursor_h.gif
cursor_h.png
cursor_v.gif
cursor_v.png
dialog-title-bg.png
filescan.png
highlighted.gif
icons-all.gif
loaderror.png
loading.gif
neweditor-tab-bg.png
pagebreak.gif
sortable.png
spacer.gif
sparator_v.png
table-cell-align.png
tangram-colorpicker.png
toolbar_bg.png
unhighlighted.gif
upload.png
videologo.gif
wordpaste.png
dialogbase.css
iframe.css
third-party
codemirror
codemirror.css
highcharts
snapscreen
UEditorSnapscreen.exe
SyntaxHighlighter
shCoreDefault.css
video-js.css
video-js.min.css
video-js.swf
webuploader
Uploader.swf
webuploader.css
zeroclipboard
ZeroClipboard.swf
jquery-1.10.2.min.map
pic_10.jpg
pic_11.jpg
pic_12.jpg
pic_13.jpg
pic_14.jpg
pic_15.jpg
pic_16.jpg
pic_17.jpg
pic_18.jpg
pic_19.jpg
pic_20.jpg
banner.jpg
userprofile
robots.txt
使用说明.txt
* version: ueditor
* build: Thu May 29 :49 GMT+0800 (中国标准时间)
(function(){
// editor.js
UEDITOR_CONFIG = window.UEDITOR_CONFIG || {};
var baidu = window.baidu || {};
window.baidu =
window.UE = baidu.editor =
window.UE || {};
UE.plugins = {};
UE.commands = {};
UE.instants = {};
UE.I18N = {};
UE._customizeUI = {};
UE.version = &1.4.3&;
var dom = UE.dom = {};
// core/browser.js
* 浏览器判断模??
* @module UE.browser
* @since 1.2.6.1
* 提供浏览器检测的模块
* @module UE.browser
var browser = UE.browser = function(){
var agent = navigator.userAgent.toLowerCase(),
opera = window.opera,
browser = {
* @property {boolean} ie 检测当前浏览器是否为IE
* @example
* ```javascript
* if ( UE.browser.ie ) {
console.log( '当前浏览器是IE' );
/(msie\s|trident.*rv:)([\w.]+)/.test(agent),
* @property {boolean} opera 检测当前浏览器是否为Opera
* @example
* ```javascript
* if ( UE.browser.opera ) {
console.log( '当前浏览器是Opera' );
opera : ( !!opera && opera.version ),
* @property {boolean} webkit 检测当前浏览器是否是webkit内核的浏览器
* @example
* ```javascript
* if ( UE.browser.webkit ) {
console.log( '当前浏览器是webkit内核浏览?? );
webkit : ( agent.indexOf( ' applewebkit/' ) & -1 ),
* @property {boolean} mac 检测当前浏览器是否是运行在mac平台??
* @example
* ```javascript
* if ( UE.browser.mac ) {
console.log( '当前浏览器运行在mac平台?? );
mac : ( agent.indexOf( 'macintosh' ) & -1 ),
* @property {boolean} quirks 检测当前浏览器是否处于“怪异模式”下
* @example
* ```javascript
* if ( UE.browser.quirks ) {
console.log( '当前浏览器运行处于“怪异模式?? );
quirks : ( patMode == 'BackCompat' )
* @property {boolean} gecko 检测当前浏览器内核是否是gecko内核
* @example
* ```javascript
* if ( UE.browser.gecko ) {
console.log( '当前浏览器内核是gecko内核' );
browser.gecko =( navigator.product == 'Gecko' && !browser.webkit && !browser.opera && !browser.ie);
var version = 0;
// Internet Explorer 6.0+
if ( browser.ie ){
agent.match(/(?:msie\s([\w.]+))/);
var v2 = agent.match(/(?:trident.*rv:([\w.]+))/);
if(v1 && v2 && v1[1] && v2[1]){
version = Math.max(v1[1]*1,v2[1]*1);
}else if(v1 && v1[1]){
version = v1[1]*1;
}else if(v2 && v2[1]){
version = v2[1]*1;
version = 0;
browser.ie11Compat = document.documentMode == 11;
* @property { boolean } ie9Compat 检测浏览器模式是否??IE9 兼容模式
* @warning 如果浏览器不是IE??则该值为undefined
* @example
* ```javascript
* if ( UE.browser.ie9Compat ) {
console.log( '当前浏览器运行在IE9兼容模式?? );
browser.ie9Compat = document.documentMode == 9;
* @property { boolean } ie8 检测浏览器是否是IE8浏览??
* @warning 如果浏览器不是IE??则该值为undefined
* @example
* ```javascript
* if ( UE.browser.ie8 ) {
console.log( '当前浏览器是IE8浏览?? );
browser.ie8 = !!document.documentM
* @property { boolean } ie8Compat 检测浏览器模式是否??IE8 兼容模式
* @warning 如果浏览器不是IE??则该值为undefined
* @example
* ```javascript
* if ( UE.browser.ie8Compat ) {
console.log( '当前浏览器运行在IE8兼容模式?? );
browser.ie8Compat = document.documentMode == 8;
* @property { boolean } ie7Compat 检测浏览器模式是否??IE7 兼容模式
* @warning 如果浏览器不是IE??则该值为undefined
* @example
* ```javascript
* if ( UE.browser.ie7Compat ) {
console.log( '当前浏览器运行在IE7兼容模式?? );
browser.ie7Compat = ( ( version == 7 && !document.documentMode )
|| document.documentMode == 7 );
* @property { boolean } ie6Compat 检测浏览器模式是否??IE6 模式 或者怪异模式
* @warning 如果浏览器不是IE??则该值为undefined
* @example
* ```javascript
* if ( UE.browser.ie6Compat ) {
console.log( '当前浏览器运行在IE6模式或者怪异模式?? );
browser.ie6Compat = ( version & 7 || browser.quirks );
browser.ie9above = version & 8;
browser.ie9below = version & 9;
browser.ie11above = version & 10;
browser.ie11below = version & 11;
if ( browser.gecko ){
var geckoRelease = agent.match( /rv:([\d\.]+)/ );
if ( geckoRelease )
geckoRelease = geckoRelease[1].split( '.' );
version = geckoRelease[0] * 10000 + ( geckoRelease[1] || 0 ) * 100 + ( geckoRelease[2] || 0 ) * 1;
* @property { Number } chrome 检测当前浏览器是否为Chrome, 如果是,则返回Chrome的大版本??
* @warning 如果浏览器不是chrome??则该值为undefined
* @example
* ```javascript
* if ( UE.browser.chrome ) {
console.log( '当前浏览器是Chrome' );
if (/chrome\/(\d+\.\d)/i.test(agent)) {
browser.chrome = + RegExp['\x241'];
* @property { Number } safari 检测当前浏览器是否为Safari, 如果是,则返回Safari的大版本??
* @warning 如果浏览器不是safari??则该值为undefined
* @example
* ```javascript
* if ( UE.browser.safari ) {
console.log( '当前浏览器是Safari' );
if(/(\d+\.\d)?(?:\.\d)?\s+safari\/?(\d+\.\d+)?/i.test(agent) && !/chrome/i.test(agent)){
browser.safari = + (RegExp['\x241'] || RegExp['\x242']);
// Opera 9.50+
if ( browser.opera )
version = parseFloat( opera.version() );
// WebKit 522+ (Safari 3+)
if ( browser.webkit )
version = parseFloat( agent.match( / applewebkit\/(\d+)/ )[1] );
* @property { Number } version 检测当前浏览器版本??
&li&IE系列返回值为5,6,7,8,9,10??/li&
&li&gecko系列会返????/li&
&li&webkit系列会返回其build??(??522??&/li&
* @example
* ```javascript
* console.log( '当前浏览器版本号是: ' + UE.browser.version );
browser.version =
* @property { boolean } isCompatible 检测当前浏览器是否能够与UEditor良好兼容
* @example
* ```javascript
* if ( UE.browser.isCompatible ) {
console.log( '浏览器与UEditor能够良好兼容' );
browser.isCompatible =
!browser.mobile && (
( browser.ie && version &= 6 ) ||
( browser.gecko && version &= 10801 ) ||
( browser.opera && version &= 9.5 ) ||
( browser.air && version &= 1 ) ||
( browser.webkit && version &= 522 ) ||
//快捷方式
var ie = browser.ie,
webkit = browser.webkit,
gecko = browser.gecko,
opera = browser.
// core/utils.js
* 工具函数??
* @module UE.utils
* @since 1.2.6.1
* UEditor封装使用的静态工具函??
* @module UE.utils
var utils = UE.utils = {
* 用给定的迭代器遍历对??
* @method each
* @param { Object } obj 需要遍历的对象
* @param { Function } iterator 迭代器, 该方法接受两个参数, 第一个参数是当前所处理的value??第二个参数是当前遍历对象的key
* @example
* ```javascript
* var demoObj = {
* //output: key1: 1, key2: 2
* UE.utils.each( demoObj, funciton ( value, key ) {
console.log( key + &:& + value );
* 用给定的迭代器遍历数组或类数组对??
* @method each
* @param { Array } array 需要遍历的数组或者类数组
* @param { Function } iterator 迭代器, 该方法接受两个参数, 第一个参数是当前所处理的value??第二个参数是当前遍历对象的key
* @example
* ```javascript
* var divs = document.getElmentByTagNames( &div& );
* //output: 0: DIV, 1: DIV ...
* UE.utils.each( divs, funciton ( value, key ) {
console.log( key + &:& + value.tagName );
each : function(obj, iterator, context) {
if (obj == null)
if (obj.length === +obj.length) {
for (var i = 0, l = obj. i & i++) {
if(iterator.call(context, obj[i], i, obj) === false)
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if(iterator.call(context, obj[key], key, obj) === false)
* 以给定对象作为原型创建一个新对象
* @method makeInstance
* @param { Object } protoObject 该对象将作为新创建对象的原型
* @return { Object } 新的对象??该对象的原型是给定的protoObject对象
* @example
* ```javascript
* var protoObject = { sayHello: function () { console.log('Hello UEditor!'); } };
* var newObject = UE.utils.makeInstance( protoObject );
* //output: Hello UEditor!
* newObject.sayHello();
makeInstance:function (obj) {
var noop = new Function();
noop.prototype =
noop.prototype =
* 将source对象中的属性扩展到target对象??
* @method extend
* @remind 该方法将强制把source对象上的属性复制到target对象??
* @see UE.utils.extend(Object,Object,Boolean)
* @param { Object } target 目标对象??新的属性将附加到该对象??
* @param { Object } source 源对象, 该对象的属性会被附加到target对象??
* @return { Object } 返回target对象
* @example
* ```javascript
* var target = { name: 'target', sex: 1 },
source = { name: 'source', age: 17 };
* UE.utils.extend( target, source );
* //output: { name: 'source', sex: 1, age: 17 }
* console.log( target );
* 将source对象中的属性扩展到target对象上, 根据指定的isKeepTarget值决定是否保留目标对象中??
* 源对象属性名相同的属性值??
* @method extend
* @param { Object } target 目标对象??新的属性将附加到该对象??
* @param { Object } source 源对象, 该对象的属性会被附加到target对象??
* @param { Boolean } isKeepTarget 是否保留目标对象中与源对象中属性名相同的属??
* @return { Object } 返回target对象
* @example
* ```javascript
* var target = { name: 'target', sex: 1 },
source = { name: 'source', age: 17 };
* UE.utils.extend( target, source, true );
* //output: { name: 'target', sex: 1, age: 17 }
* console.log( target );
extend:function (t, s, b) {
for (var k in s) {
if (!b || !t.hasOwnProperty(k)) {
t[k] = s[k];
* 将给定的多个对象的属性复制到目标对象target??
* @method extend2
* @remind 该方法将强制把源对象上的属性复制到target对象??
* @remind 该方法支持两个及以上的参数, 从第二个参数开始, 其属性都会被复制到第一个参数上??如果遇到同名的属性,
将会覆盖掉之前的值??
* @param { Object } target 目标对象??新的属性将附加到该对象??
* @param { Object... } source 源对象, 支持多个对象??该对象的属性会被附加到target对象??
* @return { Object } 返回target对象
* @example
* ```javascript
* var target = {},
source1 = { name: 'source', age: 17 },
source2 = { title: 'dev' };
* UE.utils.extend2( target, source1, source2 );
* //output: { name: 'source', age: 17, title: 'dev' }
* console.log( target );
extend2:function (t) {
for (var i = 1; i & a. i++) {
var x = a[i];
for (var k in x) {
if (!t.hasOwnProperty(k)) {
t[k] = x[k];
* 模拟继承机制??使得subClass继承自superClass
* @method inherits
* @param { Object } subClass 子类对象
* @param { Object } superClass 超类对象
* @warning 该方法只能让subClass继承超类的原型, subClass对象自身的属性和方法不会被继??
* @return { Object } 继承superClass后的子类对象
* @example
* ```javascript
* function SuperClass(){
this.name = &小李&;
* SuperClass.prototype = {
hello:function(str){
console.log(this.name + str);
* function SubClass(){
this.name = &小张&;
* UE.utils.inherits(SubClass,SuperClass);
* var sub = new SubClass();
* //output: '小张早上??
* sub.hello(&早上??&);
inherits:function (subClass, superClass) {
var oldP = subClass.prototype,
newP = utils.makeInstance(superClass.prototype);
utils.extend(newP, oldP, true);
subClass.prototype = newP;
return (newP.constructor = subClass);
* 用指定的context对象作为函数fn的上下文
* @method bind
* @param { Function } fn 需要绑定上下文的函数对??
* @param { Object } content 函数fn新的上下文对??
* @return { Function } 一个新的函数, 该函数作为原始函数fn的代理, 将完成fn的上下文调换工作??
* @example
* ```javascript
* var name = 'window',
* function test () {
console.log( this.name );
* newTest = UE.utils.bind( test, { name: 'object' } );
* //output: object
* newTest();
* //output: window
bind:function (fn, context) {
return function () {
return fn.apply(context, arguments);
* 创建延迟指定时间后执行的函数fn
* @method defer
* @param { Function } fn 需要延迟执行的函数对象
* @param { int } delay 延迟的时间, 单位是毫??
* @warning 该方法的时间控制是不精确的,仅仅只能保证函数的执行是在给定的时间之后??
而不能保证刚好到达延迟时间时执行??
* @return { Function } 目标函数fn的代理函数, 只有执行该函数才能起到延时效??
* @example
* ```javascript
* var start = 0;
* function test(){
console.log( new Date() - start );
* var testDefer = UE.utils.defer( test, 1000 );
* start = new Date();
* //output: (大约??000毫秒之后输出) 1000
* testDefer();
* 创建延迟指定时间后执行的函数fn, 如果在延迟时间内再次执行该方法, 将会根据指定的exclusion的值,
* 决定是否取消前一次函数的执行??如果exclusion的值为true??则取消执行,反之,将继续执行前一个方法??
* @method defer
* @param { Function } fn 需要延迟执行的函数对象
* @param { int } delay 延迟的时间, 单位是毫??
* @param { Boolean } exclusion 如果在延迟时间内再次执行该函数,该值将决定是否取消执行前一次函数的执行??
值为true表示取消执行??反之则将在执行前一次函数之后才执行本次函数调用??
* @warning 该方法的时间控制是不精确的,仅仅只能保证函数的执行是在给定的时间之后??
而不能保证刚好到达延迟时间时执行??
* @return { Function } 目标函数fn的代理函数, 只有执行该函数才能起到延时效??
* @example
* ```javascript
* function test(){
console.log(1);
* var testDefer = UE.utils.defer( test, 1000, true );
* //output: (两次调用仅有一次输?? 1
* testDefer();
* testDefer();
defer:function (fn, delay, exclusion) {
var timerID;
return function () {
if (exclusion) {
clearTimeout(timerID);
timerID = setTimeout(fn, delay);
* 获取元素item在数组array中首次出现的位置, 如果未找到item??则返??1
* @method indexOf
* @remind 该方法的匹配过程使用的是恒等??==??
* @param { Array } array 需要查找的数组对象
* @param { * } item 需要在目标数组中查找的??
* @return { int } 返回item在目标数组array中首次出现的位置??如果在数组中未找到item??则返??1
* @example
* ```javascript
* var item = 1,
arr = [ 3, 4, 6, 8, 1, 1, 2 ];
* //output: 4
* console.log( UE.utils.indexOf( arr, item ) );
* 获取元素item数组array中首次出现的位置, 如果未找到item??则返??1。通过start的值可以指定搜索的起始位置??
* @method indexOf
* @remind 该方法的匹配过程使用的是恒等??==??
* @param { Array } array 需要查找的数组对象
* @param { * } item 需要在目标数组中查找的??
* @param { int } start 搜索的起始位??
* @return { int } 返回item在目标数组array中的start位置之后首次出现的位置, 如果在数组中未找到item??则返??1
* @example
* ```javascript
* var item = 1,
arr = [ 3, 4, 6, 8, 1, 2, 8, 3, 2, 1, 1, 4 ];
* //output: 9
* console.log( UE.utils.indexOf( arr, item, 5 ) );
indexOf:function (array, item, start) {
var index = -1;
start = this.isNumber(start) ? start : 0;
this.each(array, function (v, i) {
if (i &= start && v === item) {
* 移除数组array中所有的元素item
* @method removeItem
* @param { Array } array 要移除元素的目标数组
* @param { * } item 将要被移除的元素
* @remind 该方法的匹配过程使用的是恒等??==??
* @example
* ```javascript
* var arr = [ 4, 5, 7, 1, 3, 4, 6 ];
* UE.utils.removeItem( arr, 4 );
* //output: [ 5, 7, 1, 3, 6 ]
* console.log( arr );
removeItem:function (array, item) {
for (var i = 0, l = array. i & i++) {
if (array[i] === item) {
array.splice(i, 1);
* 删除字符串str的首尾空??
* @method trim
* @param { String } str 需要删除首尾空格的字符??
* @return { String } 删除了首尾的空格后的字符??
* @example
* ```javascript
* var str = & UEdtior &;
* //output: 9
* console.log( str.length );
* //output: 7
* console.log( UE.utils.trim( & UEdtior & ).length );
* //output: 9
* console.log( str.length );
trim:function (str) {
return str.replace(/(^[ \t\n\r]+)|([ \t\n\r]+$)/g, '');
* 将字符串str??,'分隔成数组后,将该数组转换成哈希对象??其生成的hash对象的key为数组中的元素, value??
* @method listToMap
* @warning 该方法在生成的hash对象中,会为每一个key同时生成一个另一个全大写的key??
* @param { String } str 该字符串将被??,'分割为数组, 然后进行转化
* @return { Object } 转化之后的hash对象
* @example
* ```javascript
* //output: Object {UEdtior: 1, UEDTIOR: 1, Hello: 1, HELLO: 1}
* console.log( UE.utils.listToMap( 'UEdtior,Hello' ) );
* 将字符串数组转换成哈希对象, 其生成的hash对象的key为数组中的元素, value??
* @method listToMap
* @warning 该方法在生成的hash对象中,会为每一个key同时生成一个另一个全大写的key??
* @param { Array } arr 字符串数??
* @return { Object } 转化之后的hash对象
* @example
* ```javascript
* //output: Object {UEdtior: 1, UEDTIOR: 1, Hello: 1, HELLO: 1}
* console.log( UE.utils.listToMap( [ 'UEdtior', 'Hello' ] ) );
listToMap:function (list) {
if (!list)return {};
list = utils.isArray(list) ? list : list.split(',');
for (var i = 0, ci, obj = {}; ci = list[i++];) {
obj[ci.toUpperCase()] = obj[ci] = 1;
* 将str中的html符号转义,将转义??????????”五个字??
* @method unhtml
* @param { String } str 需要转义的字符??
* @return { String } 转义后的字符??
* @example
* ```javascript
* var html = '&body&&&/body&';
* //output: &body&&&/body&
* console.log( UE.utils.unhtml( html ) );
unhtml:function (str, reg) {
return str ? str.replace(reg || /[&&&&'](?:(amp|lt|quot|gt|#39|nbsp|#\d+);)?/g, function (a, b) {
'&':'&',
'&':'&',
'&':'&',
'&':'&',
&'&:'''
}) : '';
* 将str中的转义字符还原成html字符
* @see UE.utils.unhtml(String);
* @method html
* @param { String } str 需要逆转义的字符??
* @return { String } 逆转义后的字符串
* @example
* ```javascript
* var str = '&body&&&/body&';
* //output: &body&&&/body&
* console.log( UE.utils.html( str ) );
html:function (str) {
return str ? str.replace(/&((g|l|quo)t|amp|#39|nbsp);/g, function (m) {
'&':'&',
'&':'&',
'&':'&',
'&':'&',
''':&'&,
'&':' '
}) : '';
* 将css样式转换为驼峰的形式
* @method cssStyleToDomStyle
* @param { String } cssName 需要转换的css样式??
* @return { String } 转换成驼峰形式后的css样式??
* @example
* ```javascript
* var str = 'border-top';
* //output: borderTop
* console.log( UE.utils.cssStyleToDomStyle( str ) );
cssStyleToDomStyle:function () {
var test = document.createElement('div').style,
'float':test.cssFloat != undefined ? 'cssFloat' : test.styleFloat != undefined ? 'styleFloat' : 'float'
return function (cssName) {
return cache[cssName] || (cache[cssName] = cssName.toLowerCase().replace(/-./g, function (match) {
return match.charAt(1).toUpperCase();
* 动态加载文件到doc??
* @method loadFile
* @param { DomDocument } document 需要加载资源文件的文档对象
* @param { Object } options 加载资源文件的属性集合, 取值请参考代码示??
* @example
* ```javascript
* UE.utils.loadFile( document, {
src:&test.js&,
tag:&script&,
type:&text/javascript&,
defer:&defer&
* 动态加载文件到doc中,加载成功后执行的回调函数fn
* @method loadFile
* @param { DomDocument } document 需要加载资源文件的文档对象
* @param { Object } options 加载资源文件的属性集合, 该集合支持的值是script标签和style标签支持的所有属性??
* @param { Function } fn 资源文件加载成功之后执行的回??
* @warning 对于在同一个文档中多次加载同一URL的文件, 该方法会在第一次加载之后缓存该请求??
在此之后的所有同一URL的请求, 将会直接触发回调??
* @example
* ```javascript
* UE.utils.loadFile( document, {
src:&test.js&,
tag:&script&,
type:&text/javascript&,
defer:&defer&
* }, function () {
console.log('加载成功');
loadFile:function () {
var tmpList = [];
function getItem(doc, obj) {
for (var i = 0, ci = tmpList[i++];) {
if (ci.doc === doc && ci.url == (obj.src || obj.href)) {
} catch (e) {
return function (doc, obj, fn) {
var item = getItem(doc, obj);
if (item) {
if (item.ready) {
fn && fn();
item.funs.push(fn)
tmpList.push({
url:obj.src || obj.href,
if (!doc.body) {
var html = [];
for (var p in obj) {
if (p == 'tag')
html.push(p + '=&' + obj[p] + '&')
doc.write('&' + obj.tag + ' ' + html.join(' ') + ' &&/' + obj.tag + '&');
if (obj.id && doc.getElementById(obj.id)) {
var element = doc.createElement(obj.tag);
delete obj.
for (var p in obj) {
element.setAttribute(p, obj[p]);
element.onload = element.onreadystatechange = function () {
if (!this.readyState || /loaded|complete/.test(this.readyState)) {
item = getItem(doc, obj);
if (item.funs.length & 0) {
item.ready = 1;
for ( fi = item.funs.pop();) {
element.onload = element.onreadystatechange =
element.onerror = function () {
throw Error('The load ' + (obj.href || obj.src) + ' fails,check the url settings of file ueditor.config.js ')
doc.getElementsByTagName(&head&)[0].appendChild(element);
* 判断obj对象是否为空
* @method isEmptyObject
* @param { * } obj 需要判断的对象
* @remind 如果判断的对象是NULL??将直接返回true??如果是数组且为空??返回true??如果是字符串??且字符串为空??
返回true??如果是普通对象, 且该对象没有任何实例属性, 返回true
* @return { Boolean } 对象是否为空
* @example
* ```javascript
* //output: true
* console.log( UE.utils.isEmptyObject( {} ) );
* //output: true
* console.log( UE.utils.isEmptyObject( [] ) );
* //output: true
* console.log( UE.utils.isEmptyObject( && ) );
* //output: false
* console.log( UE.utils.isEmptyObject( { key: 1 } ) );
* //output: false
* console.log( UE.utils.isEmptyObject( [1] ) );
* //output: false
* console.log( UE.utils.isEmptyObject( &1& ) );
isEmptyObject:function (obj) {
if (obj == null)
if (this.isArray(obj) || this.isString(obj)) return obj.length === 0;
for (var key in obj) if (obj.hasOwnProperty(key))
* 把rgb格式的颜色值转换成16进制格式
* @method fixColor
* @param { String } rgb格式的颜色??
* @param { String }
* @example
* rgb(255,255,255)
=& &#ffffff&
fixColor:function (name, value) {
if (/color/i.test(name) && /rgba?/.test(value)) {
var array = value.split(&,&);
if (array.length & 3)
return &&;
value = &#&;
for (var i = 0, color = array[i++];) {
color = parseInt(color.replace(/[^\d]/gi, ''), 10).toString(16);
value += color.length == 1 ? &0& + color :
value = value.toUpperCase();
* 只针对border,padding,margin做了处理,因为性能问题
* @function
* @param {String}
val style字符??
optCss:function (val) {
var padding, margin,
val = val.replace(/(padding|margin|border)\-([^:]+):([^;]+);?/gi, function (str, key, name, val) {
if (val.split(' ').length == 1) {
switch (key) {
case 'padding':
!padding && (padding = {});
padding[name] =
return '';
case 'margin':
!margin && (margin = {});
margin[name] =
return '';
case 'border':
return val == 'initial' ? '' :
function opt(obj, name) {
if (!obj) {
return '';
var t = obj.top , b = obj.bottom, l = obj.left, r = obj.right, val = '';
if (!t || !l || !b || !r) {
for (var p in obj) {
val += ';' + name + '-' + p + ':' + obj[p] + ';';
val += ';' + name + ':' +
(t == b && b == l && l == r ? t :
t == b && l == r ? (t + ' ' + l) :
l == r ? (t + ' ' + l + ' ' + b) : (t + ' ' + r + ' ' + b + ' ' + l)) + ';'
val += opt(padding, 'padding') + opt(margin, 'margin');
return val.replace(/^[ \n\r\t;]*|[ \n\r\t]*$/, '').replace(/;([ \n\r\t]+)|\1;/g, ';')
.replace(/(&((l|g)t|quot|#39))?;{2,}/g, function (a, b) {
return b ? b + &;;& : ';'
* 克隆对象
* @method clone
* @param { Object } source 源对??
* @return { Object } source的一个副??
* 深度克隆对象,将source的属性克隆到target对象??会覆盖target重名的属性??
* @method clone
* @param { Object } source 源对??
* @param { Object } target 目标对象
* @return { Object } 附加了source对象所有属性的target对象
clone:function (source, target) {
target = target || {};
for (var i in source) {
if (source.hasOwnProperty(i)) {
tmp = source[i];
if (typeof tmp == 'object') {
target[i] = utils.isArray(tmp) ? [] : {};
utils.clone(source[i], target[i])
target[i] =
* 把cm/pt为单位的值转换为px为单位的??
* @method transUnitToPx
* @param { String } 待转换的带单位的字符??
* @return { String } 转换为px为计量单位的值的字符??
* @example
* ```javascript
* //output: 500px
* console.log( UE.utils.transUnitToPx( '20cm' ) );
* //output: 27px
* console.log( UE.utils.transUnitToPx( '20pt' ) );
transUnitToPx:function (val) {
if (!/(pt|cm)/.test(val)) {
return val
val.replace(/([\d.]+)(\w+)/, function (str, v, u) {
switch (unit) {
case 'cm':
val = parseFloat(val) * 25;
case 'pt':
val = Math.round(parseFloat(val) * 96 / 72);
return val + (val ? 'px' : '');
* 在dom树ready之后执行给定的回调函??
* @method domReady
* @remind 如果在执行该方法的时候, dom树已经ready??那么回调函数将立刻执??
* @param { Function } fn dom树ready之后的回调函??
* @example
* ```javascript
* UE.utils.domReady( function () {
console.log('123');
domReady:function () {
var fnArr = [];
function doReady(doc) {
//确保onready只执行一??
doc.isReady =
for ( ci = fnArr.pop(); ci()) {
return function (onready, win) {
win = win ||
var doc = win.
onready && fnArr.push(onready);
if (doc.readyState === &complete&) {
doReady(doc);
doc.isReady && doReady(doc);
if (browser.ie && browser.version != 11) {
(function () {
if (doc.isReady)
doc.documentElement.doScroll(&left&);
} catch (error) {
setTimeout(arguments.callee, 0);
doReady(doc);
win.attachEvent('onload', function () {
doReady(doc)
doc.addEventListener(&DOMContentLoaded&, function () {
doc.removeEventListener(&DOMContentLoaded&, arguments.callee, false);
doReady(doc);
}, false);
win.addEventListener('load', function () {
doReady(doc)
}, false);
* 动态添加css样式
* @method cssRule
* @param { String } 节点名称
* @grammar UE.utils.cssRule('添加的样式的节点名称',['样式'??放到哪个document??])
* @grammar UE.utils.cssRule('body','body{background:#ccc}') =& null
//给body添加背景颜色
* @grammar UE.utils.cssRule('body') =&样式的字符串
//取得key值为body的样式的内容,如果没有找到key值先关的样式将返回空,例如刚才那个背景颜色,将返??body{background:#ccc}
* @grammar UE.utils.cssRule('body',document) =& 返回指定key的样式,并且指定是哪个document
* @grammar UE.utils.cssRule('body','') =&null //清空给定的key值的背景颜色
cssRule:browser.ie && browser.version != 11 ? function (key, style, doc) {
var indexList,
if(style === undefined || style && style.nodeType && style.nodeType == 9){
//获取样式
doc = style && style.nodeType && style.nodeType == 9 ? style : (doc || document);
indexList = doc.indexList || (doc.indexList = {});
index = indexList[key];
if(index !==
undefined){
return doc.styleSheets[index].cssText
doc = doc ||
indexList = doc.indexList || (doc.indexList = {});
index = indexList[key];
//清除样式
if(style === ''){
if(index!== undefined){
doc.styleSheets[index].cssText = '';
delete indexList[key];
return true
//添加样式
if(index!== undefined){
sheetStyle =
doc.styleSheets[index];
sheetStyle = doc.createStyleSheet('', index = doc.styleSheets.length);
indexList[key] =
sheetStyle.cssText =
}: function (key, style, doc) {
if(style === undefined || style && style.nodeType && style.nodeType == 9){
//获取样式
doc = style && style.nodeType && style.nodeType == 9 ? style : (doc || document);
node = doc.getElementById(key);
return node ? node.innerHTML :
doc = doc ||
node = doc.getElementById(key);
//清除样式
if(style === ''){
node.parentNode.removeChild(node);
return true
//添加样式
node.innerHTML =
node = doc.createElement('style');
node.innerHTML =
doc.getElementsByTagName('head')[0].appendChild(node);
sort:function(array,compareFn){
compareFn = compareFn || function(item1, item2){ return item1.localeCompare(item2);};
for(var i= 0,len = array. i& i++){
for(var j = i,length = array. j& j++){
if(compareFn(array[i], array[j]) & 0){
var t = array[i];
array[i] = array[j];
array[j] =
serializeParam:function (json) {
var strArr = [];
for (var i in json) {
//忽略默认的几个参??
if(i==&method& || i==&timeout& || i==&async&)
//传递过来的对象和函数不在提交之??
if (!((typeof json[i]).toLowerCase() == &function& || (typeof json[i]).toLowerCase() == &object&)) {
strArr.push( encodeURIComponent(i) + &=&+encodeURIComponent(json[i]) );
} else if (utils.isArray(json[i])) {
//支持传数组内??
for(var j = 0; j & json[i]. j++) {
strArr.push( encodeURIComponent(i) + &[]=&+encodeURIComponent(json[i][j]) );
return strArr.join(&&&);
formatUrl:function (url) {
var u = url.replace(/&&/g, '&');
u = u.replace(/\?&/g, '?');
u = u.replace(/&$/g, '');
u = u.replace(/&#/g, '#');
u = u.replace(/&+/g, '&');
isCrossDomainUrl:function (url) {
var a = document.createElement('a');
if (browser.ie) {
a.href = a.
return !(a.protocol == location.protocol && a.hostname == location.hostname &&
(a.port == location.port || (a.port == '80' && location.port == '') || (a.port == '' && location.port == '80')));
clearEmptyAttrs : function(obj){
for(var p in obj){
if(obj[p] === ''){
delete obj[p]
str2json : function(s){
if (!utils.isString(s))
if (window.JSON) {
return JSON.parse(s);
return (new Function(&return & + utils.trim(s || '')))();
json2str : (function(){
if (window.JSON) {
return JSON.
var escapeMap = {
&\b&: '\\b',
&\t&: '\\t',
&\n&: '\\n',
&\f&: '\\f',
&\r&: '\\r',
'&' : '\\&',
&\\&: '\\\\'
function encodeString(source) {
if (/[&\\\x00-\x1f]/.test(source)) {
source = source.replace(
/[&\\\x00-\x1f]/g,
function (match) {
var c = escapeMap[match];
c = match.charCodeAt();
return &\\u00&
+ Math.floor(c / 16).toString(16)
+ (c % 16).toString(16);
return '&' + source + '&';
function encodeArray(source) {
var result = [&[&],
l = source.length,
preComma, i,
for (i = 0; i & i++) {
item = source[i];
switch (typeof item) {
case &undefined&:
case &function&:
case &unknown&:
if(preComma) {
result.push(',');
result.push(utils.json2str(item));
preComma = 1;
result.push(&]&);
return result.join(&&);
function pad(source) {
return source & 10 ? '0' + source :
function encodeDate(source){
return '&' + source.getFullYear() + &-&
+ pad(source.getMonth() + 1) + &-&
+ pad(source.getDate()) + &T&
+ pad(source.getHours()) + &:&
+ pad(source.getMinutes()) + &:&
+ pad(source.getSeconds()) + '&';
return function (value) {
switch (typeof value) {
case 'undefined':
return 'undefined';
case 'number':
return isFinite(value) ? String(value) : &null&;
case 'string':
return encodeString(value);
case 'boolean':
return String(value);
if (value === null) {
return 'null';
} else if (utils.isArray(value)) {
return encodeArray(value);
} else if (utils.isDate(value)) {
return encodeDate(value);
var result = ['{'],
encode = utils.json2str,
for (var key in value) {
if (Object.prototype.hasOwnProperty.call(value, key)) {
item = value[key];
switch (typeof item) {
case 'undefined':
case 'unknown':
case 'function':
if (preComma) {
result.push(',');
preComma = 1;
result.push(encode(key) + ':' + encode(item));
result.push('}');
return result.join('');
* 判断给定的对象是否是字符??
* @method isString
* @param { * } object 需要判断的对象
* @return { Boolean } 给定的对象是否是字符??
* 判断给定的对象是否是数组
* @method isArray
* @param { * } object 需要判断的对象
* @return { Boolean } 给定的对象是否是数组
* 判断给定的对象是否是一个Function
* @method isFunction
* @param { * } object 需要判断的对象
* @return { Boolean } 给定的对象是否是Function
* 判断给定的对象是否是Number
* @method isNumber
* @param { * } object 需要判断的对象
* @return { Boolean } 给定的对象是否是Number
* 判断给定的对象是否是一个正则表达式
* @method isRegExp
* @param { * } object 需要判断的对象
* @return { Boolean } 给定的对象是否是正则表达??
* 判断给定的对象是否是一个普通对??
* @method isObject
* @param { * } object 需要判断的对象
* @return { Boolean } 给定的对象是否是普通对??
utils.each(['String', 'Function', 'Array', 'Number', 'RegExp', 'Object', 'Date'], function (v) {
UE.utils['is' + v] = function (obj) {
return Object.prototype.toString.apply(obj) == '[object ' + v + ']';
// core/EventBase.js
* UE采用的事件基??
* @module UE
* @class EventBase
* @since 1.2.6.1
* UEditor公用空间,UEditor所有的功能都挂载在该空间下
* @module UE
* UE采用的事件基类,继承此类的对应类将获取addListener,removeListener,fireEvent方法??
* 在UE中,Editor以及所有ui实例都继承了该类,故可以在对应的ui对象以及editor对象上使用上述方法??
* @module UE
* @class EventBase
* 通过此构造器,子类可以继承EventBase获取事件监听的方??
* @constructor
* @example
* ```javascript
* UE.EventBase.call(editor);
var EventBase = UE.EventBase = function () {};
EventBase.prototype = {
* 注册事件监听??
* @method addListener
* @param { String } types 监听的事件名称,同时监听多个事件使用空格分隔
* @param { Function } fn 监听的事件被触发时,会执行该回调函数
* @waining 事件被触发时,监听的函数假如返回的值恒等于true,回调函数的队列中后面的函数将不执行
* @example
* ```javascript
* editor.addListener('selectionchange',function(){
console.log(&选区已经变化??);
* editor.addListener('beforegetcontent aftergetcontent',function(type){
if(type == 'beforegetcontent'){
//do something
//do something
console.log(this.getContent) // this是注册的事件的编辑器实例
* @see UE.EventBase:fireEvent(String)
addListener:function (types, listener) {
types = utils.trim(types).split(/\s+/);
for (var i = 0, ti = types[i++];) {
getListener(this, ti, true).push(listener);
on : function(types, listener){
return this.addListener(types,listener);
off : function(types, listener){
return this.removeListener(types, listener)
trigger:function(){
return this.fireEvent.apply(this,arguments);
* 移除事件监听??
* @method removeListener
* @param { String } types 移除的事件名称,同时移除多个事件使用空格分隔
* @param { Function } fn 移除监听事件的函数引??
* @example
* ```javascript
* //changeCallback为方法体
* editor.removeListener(&selectionchange&,changeCallback);
removeListener:function (types, listener) {
types = utils.trim(types).split(/\s+/);
for (var i = 0, ti = types[i++];) {
utils.removeItem(getListener(this, ti) || [], listener);
* 触发事件
* @method fireEvent
* @param { String } types 触发的事件名称,同时触发多个事件使用空格分隔
* @remind 该方法会触发addListener
* @return { * } 返回触发事件的队列中,最后执行的回调函数的返回??
* @example
* ```javascript
* editor.fireEvent(&selectionchange&);
* 触发事件
* @method fireEvent
* @param { String } types 触发的事件名称,同时触发多个事件使用空格分隔
* @param { *... } options 可选参数,可以传入一个或多个参数,会传给事件触发的回调函??
* @return { * } 返回触发事件的队列中,最后执行的回调函数的返回??
* @example
* ```javascript
* editor.addListener( &selectionchange&, function ( type, arg1, arg2 ) {
console.log( arg1 + & & + arg2 );
* //触发selectionchange事件??会执行上面的事件监听??
* //output: Hello World
* editor.fireEvent(&selectionchange&, &Hello&, &World&);
fireEvent:function () {
var types = arguments[0];
types = utils.trim(types).split(' ');
for (var i = 0, ti = types[i++];) {
var listeners = getListener(this, ti),
if (listeners) {
k = listeners.
while (k--) {
if(!listeners[k])
t = listeners[k].apply(this, arguments);
if(t === true){
if (t !== undefined) {
if (t = this['on' + ti.toLowerCase()]) {
r = t.apply(this, arguments);
* 获得对象所拥有监听类型的所有监听器
* @module UE
* @since 1.2.6.1
* @method getListener
* @param { Object } obj
查询监听器的对象
* @param { String } type 事件类型
* @param { Boolean } force
为true且当前所有type类型的侦听器不存在时,创建一个空监听器数??
* @return { Array } 监听器数??
function getListener(obj, type, force) {
type = type.toLowerCase();
return ( ( allListeners = ( obj.__allListeners || force && ( obj.__allListeners = {} ) ) )
&& ( allListeners[type] || force && ( allListeners[type] = [] ) ) );
// core/dtd.js
///import editor.js
///import core/dom/dom.js
///import core/utils.js
* dtd html语义化的体现??
* @constructor
* @namespace dtd
var dtd = dom.dtd = (function() {
function _( s ) {
for (var k in s) {
s[k.toUpperCase()] = s[k];
var X = utils.extend2;
var A = _({isindex:1,fieldset:1}),
B = _({input:1,button:1,select:1,textarea:1,label:1}),
C = X( _({a:1}), B ),
D = X( {iframe:1}, C ),
E = _({hr:1,ul:1,menu:1,div:1,blockquote:1,noscript:1,table:1,center:1,address:1,dir:1,pre:1,h5:1,dl:1,h4:1,noframes:1,h6:1,ol:1,h1:1,h3:1,h2:1}),
F = _({ins:1,del:1,script:1,style:1}),
G = X( _({b:1,acronym:1,bdo:1,'var':1,'#':1,abbr:1,code:1,br:1,i:1,cite:1,kbd:1,u:1,strike:1,s:1,tt:1,strong:1,q:1,samp:1,em:1,dfn:1,span:1}), F ),
H = X( _({sub:1,img:1,embed:1,object:1,sup:1,basefont:1,map:1,applet:1,font:1,big:1,small:1}), G ),
I = X( _({p:1}), H ),
J = X( _({iframe:1}), H, B ),
K = _({img:1,embed:1,noscript:1,br:1,kbd:1,center:1,button:1,basefont:1,h5:1,h4:1,samp:1,h6:1,ol:1,h1:1,h3:1,h2:1,form:1,font:1,'#':1,select:1,menu:1,ins:1,abbr:1,label:1,code:1,table:1,script:1,cite:1,input:1,iframe:1,strong:1,textarea:1,noframes:1,big:1,small:1,span:1,hr:1,sub:1,bdo:1,'var':1,div:1,object:1,sup:1,strike:1,dir:1,map:1,dl:1,applet:1,del:1,isindex:1,fieldset:1,ul:1,b:1,acronym:1,a:1,blockquote:1,i:1,u:1,s:1,tt:1,address:1,q:1,pre:1,p:1,em:1,dfn:1}),
L = X( _({a:0}), J ),//a不能被切开,所以把??
M = _({tr:1}),
N = _({'#':1}),
O = X( _({param:1}), K ),
P = X( _({form:1}), A, D, E, I ),
Q = _({li:1,ol:1,ul:1}),
R = _({style:1,script:1}),
S = _({base:1,link:1,meta:1,title:1}),
T = X( S, R ),
U = _({head:1,body:1}),
V = _({html:1});
var block = _({address:1,blockquote:1,center:1,dir:1,div:1,dl:1,fieldset:1,form:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,isindex:1,menu:1,noframes:1,ol:1,p:1,pre:1,table:1,ul:1}),
_({area:1,base:1,basefont:1,br:1,col:1,command:1,dialog:1,embed:1,hr:1,img:1,input:1,isindex:1,keygen:1,link:1,meta:1,param:1,source:1,track:1,wbr:1});
// $ 表示自定的属??
// body外的元素列表.
$nonBodyContent: X( V, U, S ),
//块结构元素列??
$block : block,
//内联元素列表
$inline : L,
$inlineWithA : X(_({a:1}),L),
$body : X( _({script:1,style:1}), block ),
$cdata : _({script:1,style:1}),
//自闭和元??
$empty : empty,
//不是自闭合,但不能让range选中里边
$nonChild : _({iframe:1,textarea:1}),
//列表元素列表
$listItem : _({dd:1,dt:1,li:1}),
//列表根元素列??
$list: _({ul:1,ol:1,dl:1}),
//不能认为是空的元??
$isNotEmpty : _({table:1,ul:1,ol:1,dl:1,iframe:1,area:1,base:1,col:1,hr:1,img:1,embed:1,input:1,link:1,meta:1,param:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1}),
//如果没有子节点就可以删除的元素列表,像span,a
$removeEmpty : _({a:1,abbr:1,acronym:1,address:1,b:1,bdo:1,big:1,cite:1,code:1,del:1,dfn:1,em:1,font:1,i:1,ins:1,label:1,kbd:1,q:1,s:1,samp:1,small:1,span:1,strike:1,strong:1,sub:1,sup:1,tt:1,u:1,'var':1}),
$removeEmptyBlock : _({'p':1,'div':1}),
//在table元素里的元素列表
$tableContent : _({caption:1,col:1,colgroup:1,tbody:1,td:1,tfoot:1,th:1,thead:1,tr:1,table:1}),
//不转换的标签
$notTransContent : _({pre:1,script:1,style:1,textarea:1}),
script: N,
tr : _({td:1,th:1}),
embed: {},
colgroup : _({thead:1,col:1,tbody:1,tr:1,tfoot:1}),
noscript : P,
center : P,
button : X( I, E ),
basefont : {},
option : N,
form : X( A, D, E, I ),
select : _({optgroup:1,option:1}),
label : L,
table : _({thead:1,col:1,tbody:1,tr:1,colgroup:1,caption:1,tfoot:1}),
tfoot : M,
input : {},
iframe : P,
strong : L,
textarea : N,
noframes : P,
small : L,
span :_({'#':1,br:1,b:1,strong:1,u:1,i:1,em:1,sub:1,sup:1,strike:1,span:1}),
optgroup : _({option:1}),
param : {},
'var' : L,
object : O,
strike : L,
area : {},
map : X( _({area:1,form:1,p:1}), A, F, E ),
applet : O,
dl : _({dt:1,dd:1}),
isindex : {},
fieldset : X( _({legend:1}), K ),
thead : M,
acronym : L,
a : X( _({a:1}), J ),
blockquote :X(_({td:1,tr:1,tbody:1,li:1}),P),
caption : L,
tbody : M,
address : X( D, I ),
legend : L,
pre : X( G, C ),
p : X(_({'a':1}),L),
// core/domUtils.js
* Dom操作工具??
* @module UE.dom.domUtils
* @since 1.2.6.1
* Dom操作工具??
* @module UE.dom.domUtils
function getDomNode(node, start, ltr, startFromChild, fn, guard) {
var tmpNode = startFromChild && node[start],
!tmpNode && (tmpNode = node[ltr]);
while (!tmpNode && (parent = (parent || node).parentNode)) {
if (parent.tagName == 'BODY' || guard && !guard(parent)) {
tmpNode = parent[ltr];
if (tmpNode && fn && !fn(tmpNode)) {
getDomNode(tmpNode, start, ltr, false, fn);
return tmpN
var attrFix = ie && browser.version & 9 ? {
tabindex:&tabIndex&,
readonly:&readOnly&,
&for&:&htmlFor&,
&class&:&className&,
maxlength:&maxLength&,
cellspacing:&cellSpacing&,
cellpadding:&cellPadding&,
rowspan:&rowSpan&,
colspan:&colSpan&,
usemap:&useMap&,
frameborder:&frameBorder&
tabindex:&tabIndex&,
readonly:&readOnly&
styleBlock = utils.listToMap([
'-webkit-box', '-moz-box', 'block' ,
'list-item' , 'table' , 'table-row-group' ,
'table-header-group', 'table-footer-group' ,
'table-row' , 'table-column-group' , 'table-column' ,
'table-cell' , 'table-caption'
var domUtils = dom.domUtils = {
//节点常量
NODE_ELEMENT:1,
NODE_DOCUMENT:9,
NODE_TEXT:3,
NODE_COMMENT:8,
NODE_DOCUMENT_FRAGMENT:11,
//位置关系
POSITION_IDENTICAL:0,
POSITION_DISCONNECTED:1,
POSITION_FOLLOWING:2,
POSITION_PRECEDING:4,
POSITION_IS_CONTAINED:8,
POSITION_CONTAINS:16,
//ie6使用其他的会有一段空白出??
fillChar:ie && browser.version == '6' ? '\ufeff' : '\u200B',
//-------------------------Node部分--------------------------------
/*Backspace*/ 8:1, /*Delete*/ 46:1,
/*Shift*/ 16:1, /*Ctrl*/ 17:1, /*Alt*/ 18:1,
37:1, 38:1, 39:1, 40:1,
13:1 /*enter*/
* 获取节点A相对于节点B的位置关??
* @method getPosition
* @param { Node } nodeA 需要查询位置关系的节点A
* @param { Node } nodeB 需要查询位置关系的节点B
* @return { Number } 节点A与节点B的关??
* @example
* ```javascript
* //output: 20
* var position = UE.dom.domUtils.getPosition( document.documentElement, document.body );
* switch ( position ) {
case UE.dom.domUtils.POSITION_IDENTICAL:
console.log('元素相同');
case UE.dom.domUtils.POSITION_DISCONNECTED:
console.log('两个节点在不同的文档??);
case UE.dom.domUtils.POSITION_FOLLOWING:
console.log('节点A在节点B之后');
case UE.dom.domUtils.POSITION_PRECEDING;
console.log('节点A在节点B之前');
case UE.dom.domUtils.POSITION_IS_CONTAINED:
console.log('节点A被节点B包含');
console.log('节点A被节点B包含且节点A在节点B之后');
case UE.dom.domUtils.POSITION_CONTAINS:
console.log('节点A包含节点B');
console.log('节点A包含节点B且节点A在节点B之前');
getPosition:function (nodeA, nodeB) {
// 如果两个节点是同一个节??
if (nodeA === nodeB) {
// domUtils.POSITION_IDENTICAL
parentsA = [nodeA],
parentsB = [nodeB];
node = nodeA;
while (node = node.parentNode) {
// 如果nodeB是nodeA的祖先节??
if (node === nodeB) {
// domUtils.POSITION_IS_CONTAINED + domUtils.POSITION_FOLLOWING
return 10;
parentsA.push(node);
node = nodeB;
while (node = node.parentNode) {
// 如果nodeA是nodeB的祖先节??
if (node === nodeA) {
// domUtils.POSITION_CONTAINS + domUtils.POSITION_PRECEDING
return 20;
parentsB.push(node);
parentsA.reverse();
parentsB.reverse();
if (parentsA[0] !== parentsB[0]) {
// domUtils.POSITION_DISCONNECTED
var i = -1;
while (i++, parentsA[i] === parentsB[i]) {
nodeA = parentsA[i];
nodeB = parentsB[i];
while (nodeA = nodeA.nextSibling) {
if (nodeA === nodeB) {
// domUtils.POSITION_PRECEDING
// domUtils.POSITION_FOLLOWING
* 检测节点node在父节点中的索引位置
* @method getNodeIndex
* @param { Node } node 需要检测的节点对象
* @return { Number } 该节点在父节点中的位??
* @see UE.dom.domUtils.getNodeIndex(Node,Boolean)
* 检测节点node在父节点中的索引位置??根据给定的mergeTextNode参数决定是否要合并多个连续的文本节点为一个节??
* @method getNodeIndex
* @param { Node } node 需要检测的节点对象
* @param { Boolean } mergeTextNode 是否合并多个连续的文本节点为一个节??
* @return { Number } 该节点在父节点中的位??
* @example
* ```javascript
var node = document.createElement(&div&);
node.appendChild( document.createTextNode( &hello& ) );
node.appendChild( document.createTextNode( &world& ) );
node.appendChild( node = document.createElement( &div& ) );
//output: 2
console.log( UE.dom.domUtils.getNodeIndex( node ) );
//output: 1
console.log( UE.dom.domUtils.getNodeIndex( node, true ) );
getNodeIndex:function (node, ignoreTextNode) {
var preNode = node,
while (preNode = preNode.previousSibling) {
if (ignoreTextNode && preNode.nodeType == 3) {
if(preNode.nodeType != preNode.nextSibling.nodeType ){
* 检测节点node是否在给定的document对象??
* @method inDoc
* @param { Node } node 需要检测的节点对象
* @param { DomDocument } doc 需要检测的document对象
* @return { Boolean } 该节点node是否在给定的document的dom树上
* @example
* ```javascript
* var node = document.createElement(&div&);
* //output: false
* console.log( UE.do.domUtils.inDoc( node, document ) );
* document.body.appendChild( node );
* //output: true
* console.log( UE.do.domUtils.inDoc( node, document ) );
inDoc:function (node, doc) {
return domUtils.getPosition(node, doc) == 10;
* 根据给定的过滤规则filterFn??查找符合该过滤规则的node节点的第一个祖先节点,
* 查找的起点是给定node节点的父节点??
* @method findParent
* @param { Node } node 需要查找的节点
* @param { Function } filterFn 自定义的过滤方法??
* @warning 查找的终点是到body节点为止
* @remind 自定义的过滤方法filterFn接受一个Node对象作为参数??该对象代表当前执行检测的祖先节点??如果??
节点满足过滤条件??则要求返回true??这时将直接返回该节点作为findParent()的结果, 否则??请返回false??
* @return { Node | Null } 如果找到符合过滤条件的节点, 就返回该节点??否则返回NULL
* @example
* ```javascript
* var filterNode = UE.dom.domUtils.findParent( document.body.firstChild, function ( node ) {
//由于查找的终点是body节点??所以永远也不会匹配当前过滤器的条件??即这里永远会返回false
return node.tagName === &HTML&;
* //output: true
* console.log( filterNode === null );
* 根据给定的过滤规则filterFn??查找符合该过滤规则的node节点的第一个祖先节点,
* 如果includeSelf的值为true,则查找的起点是给定的节点node??否则??起点是node的父节点
* @method findParent
* @param { Node } node 需要查找的节点
* @param { Function } filterFn 自定义的过滤方法??
* @param { Boolean } includeSelf 查找过程是否包含自身
* @warning 查找的终点是到body节点为止
* @remind 自定义的过滤方法filterFn接受一个Node对象作为参数??该对象代表当前执行检测的祖先节点??如果??
节点满足过滤条件??则要求返回true??这时将直接返回该节点作为findParent()的结果, 否则??请返回false??
* @remind 如果includeSelf为true??则过滤器第一次执行时的参数会是节点本身??
反之??过滤器第一次执行时的参数将是该节点的父节点??
* @return { Node | Null } 如果找到符合过滤条件的节点, 就返回该节点??否则返回NULL
* @example
&div id=&test&&
&script type=&text/javascript&&
//output: DIV, BODY
var filterNode = UE.dom.domUtils.findParent( document.getElementById( &test& ), function ( node ) {
console.log( node.tagName );
}, true );
findParent:function (node, filterFn, includeSelf) {
if (node && !domUtils.isBody(node)) {
node = includeSelf ? node : node.parentN
while (node) {
if (!filterFn || filterFn(node) || domUtils.isBody(node)) {
return filterFn && !filterFn(node) && domUtils.isBody(node) ? null :
node = node.parentN
* 查找node的节点名为tagName的第一个祖先节点, 查找的起点是node节点的父节点??
* @method findParentByTagName
* @param { Node } node 需要查找的节点对象
* @param { Array } tagNames 需要查找的父节点的名称数组
* @warning 查找的终点是到body节点为止
* @return { Node | NULL } 如果找到符合条件的节点, 则返回该节点??否则返回NULL
* @example
* ```javascript
* var node = UE.dom.domUtils.findParentByTagName( document.getElementsByTagName(&div&)[0], [ &BODY& ] );
* //output: BODY
* console.log( node.tagName );
* 查找node的节点名为tagName的祖先节点, 如果includeSelf的值为true,则查找的起点是给定的节点node??
* 否则??起点是node的父节点??
* @method findParentByTagName
* @param { Node } node 需要查找的节点对象
* @param { Array } tagNames 需要查找的父节点的名称数组
* @param { Boolean } includeSelf 查找过程是否包含node节点自身
* @warning 查找的终点是到body节点为止
* @return { Node | NULL } 如果找到符合条件的节点, 则返回该节点??否则返回NULL
* @example
* ```javascript
* var queryTarget = document.getElementsByTagName(&div&)[0];
* var node = UE.dom.domUtils.findParentByTagName( queryTarget, [ &DIV& ], true );
* //output: true
* console.log( queryTarget === node );
findParentByTagName:function (node, tagNames, includeSelf, excludeFn) {
tagNames = utils.listToMap(utils.isArray(tagNames) ? tagNames : [tagNames]);
return domUtils.findParent(node, function (node) {
return tagNames[node.tagName] && !(excludeFn && excludeFn(node));
}, includeSelf);
* 查找节点node的祖先节点集合, 查找的起点是给定节点的父节点,结果集中不包含给定的节点??
* @method findParents
* @param { Node } node 需要查找的节点对象
* @return { Array } 给定节点的祖先节点数??
* @grammar UE.dom.domUtils.findParents(node)
//返回一个祖先节点数组集合,不包含自??
* @grammar UE.dom.domUtils.findParents(node,includeSelf)
//返回一个祖先节点数组集合,includeSelf指定是否包含自身
* @grammar UE.dom.domUtils.findParents(node,includeSelf,filterFn)
//返回一个祖先节点数组集合,filterFn指定过滤条件,返回true的node将被选取
* @grammar UE.dom.domUtils.findParents(node,includeSelf,filterFn,closerFirst)
//返回一个祖先节点数组集合,closerFirst为true的话,node的直接父亲节点是数组的第0??
* 查找节点node的祖先节点集合, 如果includeSelf的值为true??
* 则返回的结果集中允许出现当前给定的节点, 否则??该节点不会出现在其结果集中??
* @method findParents
* @param { Node } node 需要查找的节点对象
* @param { Boolean } includeSelf 查找的结果中是否允许包含当前查找的节点对??
* @return { Array } 给定节点的祖先节点数??
findParents:function (node, includeSelf, filterFn, closerFirst) {
var parents = includeSelf && ( filterFn && filterFn(node) || !filterFn ) ? [node] : [];
while (node = domUtils.findParent(node, filterFn)) {
parents.push(node);
return closerFirst ? parents : parents.reverse();
* 在节点node后面插入新节点newNode
* @method insertAfter
* @param { Node } node 目标节点
* @param { Node } newNode 新插入的节点??该节点将置于目标节点之后
* @return { Node } 新插入的节点
insertAfter:function (node, newNode) {
return node.nextSibling ? node.parentNode.insertBefore(newNode, node.nextSibling):
node.parentNode.appendChild(newNode);
* 删除节点node及其下属的所有节??
* @method remove
* @param { Node } node 需要删除的节点对象
* @return { Node } 返回刚删除的节点对象
* @example
* &div id=&test&&
&div id=&child&&你好&/div&
* &script&
UE.dom.domUtils.remove( document.body, false );
//output: false
console.log( document.getElementById( &child& ) !== null );
* &/script&
* 删除节点node,并根据keepChildren的值决定是否保留子节点
* @method remove
* @param { Node } node 需要删除的节点对象
* @param { Boolean } keepChildren 是否需要保留子节点
* @return { Node } 返回刚删除的节点对象
* @example
* &div id=&test&&
&div id=&child&&你好&/div&
* &script&
UE.dom.domUtils.remove( document.body, true );
//output: true
console.log( document.getElementById( &child& ) !== null );
* &/script&
remove:function (node, keepChildren) {
var parent = node.parentNode,
if (parent) {
if (keepChildren && node.hasChildNodes()) {
while (child = node.firstChild) {
parent.insertBefore(child, node);
parent.removeChild(node);
* 取得node节点的下一个兄弟节点, 如果该节点其后没有兄弟节点, 则递归查找其父节点之后的第一个兄弟节点,
* 直到找到满足条件的节点或者递归到BODY节点之后才会结束??
* @method getNextDomNode
* @param { Node } node 需要获取其后的兄弟节点的节点对??
* @return { Node | NULL } 如果找满足条件的节点??则返回该节点??否则返回NULL
* @example
&div id=&test&&
&span&&/span&
&i&xxx&/i&
* &script&
//output: i节点
console.log( UE.dom.domUtils.getNextDomNode( document.getElementById( &test& ) ) );
* &/script&
* @example
&span&&/span&
&i id=&test&&xxx&/i&
&b&xxx&/b&
* &script&
//由于id为test的i节点之后没有兄弟节点??则查找其父节点(div)后面的兄弟节点
//output: b节点
console.log( UE.dom.domUtils.getNextDomNode( document.getElementById( &test& ) ) );
* &/script&
* 取得node节点的下一个兄弟节点, 如果startFromChild的值为ture,则先获取其子节点,
* 如果有子节点则直接返回第一个子节点;如果没有子节点或者startFromChild的值为false??
* 则执??a href=&#UE.dom.domUtils.getNextDomNode(Node)&&getNextDomNode(Node node)&/a&的查找过程??
* @method getNextDomNode
* @param { Node } node 需要获取其后的兄弟节点的节点对??
* @param { Boolean } startFromChild 查找过程是否从其子节点开??
* @return { Node | NULL } 如果找满足条件的节点??则返回该节点??否则返回NULL
* @see UE.dom.domUtils.getNextDomNode(Node)
getNextDomNode:function (node, startFromChild, filterFn, guard) {
return getDomNode(node, 'firstChild', 'nextSibling', startFromChild, filterFn, guard);
getPreDomNode:function (node, startFromChild, filterFn, guard) {
return getDomNode(node, 'lastChild', 'previousSibling', startFromChild, filterFn, guard);
* 检测节点node是否属是UEditor定义的bookmark节点
* @method isBookmarkNode
* @private
* @param { Node } node 需要检测的节点对象
* @return { Boolean } 是否是bookmark节点
* @example
* &span id=&_baidu_bookmark_1&&&/span&
* &script&
var bookmarkNode = document.getElementById(&_baidu_bookmark_1&);
//output: true
console.log( UE.dom.domUtils.isBookmarkNode( bookmarkNode ) );
* &/script&
isBookmarkNode:function (node) {
return node.nodeType == 1 && node.id && /^_baidu_bookmark_/i.test(node.id);
* 获取节点node所属的window对象
* @param { Node } node 节点对象
* @return { Window } 当前节点所属的window对象
* @example
* ```javascript
* //output: true
* console.log( UE.dom.domUtils.getWindow( document.body ) === window );
getWindow:function (node) {
var doc = node.ownerDocument ||
return doc.defaultView || doc.parentW
* 获取离nodeA与nodeB最近的公共的祖先节??
getCommonAncestor
* @param { Node } nodeA 第一个节??
* @param { Node } nodeB 第二个节??
* @remind 如果给定的两个节点是同一个节点, 将直接返回该节点??
* @return { Node | NULL } 如果未找到公共节点, 返回NULL??否则返回最近的公共祖先节点??
* @example
* ```javascript
* var commonAncestor = UE.dom.domUtils.getCommonAncestor( document.body, document.body.firstChild );
* //output: true
* console.log( commonAncestor.tagName.toLowerCase() === 'body' );
getCommonAncestor:function (nodeA, nodeB) {
if (nodeA === nodeB)
return nodeA;
var parentsA = [nodeA] , parentsB = [nodeB], parent = nodeA, i = -1;
while (parent = parent.parentNode) {
if (parent === nodeB) {
parentsA.push(parent);
parent = nodeB;
while (parent = parent.parentNode) {
if (parent === nodeA)
parentsB.push(parent);
parentsA.reverse();
parentsB.reverse();
while (i++, parentsA[i] === parentsB[i]) {
return i == 0 ? null : parentsA[i - 1];
* 清除node节点左右连续为空的兄弟inline节点
* @method clearEmptySibling
* @param { Node } node 执行的节点对象, 如果该节点的左右连续的兄弟节点是空的inline节点??
* 则这些兄弟节点将被删??
* @grammar UE.dom.domUtils.clearEmptySibling(node,ignoreNext)
//ignoreNext指定是否忽略右边空节??
* @grammar UE.dom.domUtils.clearEmptySibling(node,ignoreNext,ignorePre)
//ignorePre指定是否忽略左边空节??
* @example
&div&&/div&
&span id=&test&&&/span&
&em&xxx&/em&
&span&&/span&
* &script&
UE.dom.domUtils.clearEmptySibling( document.getElementById( &test& ) );
//output: &div&&/div&&span id=&test&&&/span&&em&xxx&/em&&span&&/span&
console.log( document.body.innerHTML );
* &/script&
* 清除node节点左右连续为空的兄弟inline节点??如果ignoreNext的值为true??
* 则忽略对右边兄弟节点的操作??
* @method clearEmptySibling
* @param { Node } node 执行的节点对象, 如果该节点的左右连续的兄弟节点是空的inline节点??
* @param { Boolean } ignoreNext 是否忽略忽略对右边的兄弟节点的操??
* 则这些兄弟节点将被删??
* @see UE.dom.domUtils.clearEmptySibling(Node)
* 清除node节点左右连续为空的兄弟inline节点??如果ignoreNext的值为true??
* 则忽略对右边兄弟节点的操作, 如果ignorePre的值为true,则忽略对左边兄弟节点的操作??
* @method clearEmptySibling
* @param { Node } node 执行的节点对象, 如果该节点的左右连续的兄弟节点是空的inline节点??
* @param { Boolean } ignoreNext 是否忽略忽略对右边的兄弟节点的操??
* @param { Boolean } ignorePre 是否忽略忽略对左边的兄弟节点的操??
* 则这些兄弟节点将被删??
* @see UE.dom.domUtils.clearEmptySibling(Node)
clearEmptySibling:function (node, ignoreNext, ignorePre) {
function clear(next, dir) {
while (next && !domUtils.isBookmarkNode(next) && (domUtils.isEmptyInlineElement(next)
//这里不能把空格算进来会吧空格干掉,出现文字间的空格丢掉了
|| !new RegExp('[^\t\n\r' + domUtils.fillChar + ']').test(next.nodeValue) )) {
tmpNode = next[dir];
domUtils.remove(next);
next = tmpN
!ignoreNext && clear(node.nextSibling, 'nextSibling');
!ignorePre && clear(node.previousSibling, 'previousSibling');
* 将一个文本节点textNode拆分成两个文本节点,offset指定拆分位置
* @method split
* @param { Node } textNode 需要拆分的文本节点对象
* @param { int } offset 需要拆分的位置??位置计算??开??
* @return { Node } 拆分后形成的新节??
* @example
* &div id=&test&&abcdef&/div&
* &script&
var newNode = UE.dom.domUtils.split( document.getElementById( &test& ).firstChild, 3 );
//output: def
console.log( newNode.nodeValue );
* &/script&
split:function (node, offset) {
var doc = node.ownerD
if (browser.ie && offset == node.nodeValue.length) {
var next = doc.createTextNode('');
return domUtils.insertAfter(node, next);
var retval = node.splitText(offset);
//ie8下splitText不会跟新childNodes,我们手动触发他的更新
if (browser.ie8) {
var tmpNode = doc.createTextNode('');
domUtils.insertAfter(retval, tmpNode);
domUtils.remove(tmpNode);
* 检测文本节点textNode是否为空节点(包括空格、换行、占位符等字符)
isWhitespace
* @param { Node } node 需要检测的节点对象
* @return { Boolean } 检测的节点是否为空
* @example
* &div id=&test&&
* &script&
//output: true
console.log( UE.dom.domUtils.isWhitespace( document.getElementById(&test&).firstChild ) );
* &/script&
isWhitespace:function (node) {
return !new RegExp('[^ \t\n\r' + domUtils.fillChar + ']').test(node.nodeValue);
* 获取元素element相对于viewport的位置坐??
* @method getXY
* @param { Node } element 需要计算位置的节点对象
* @return { Object } 返回形如{x:left,y:top}的一个key-value映射对象??其中键x代表水平偏移距离??
y代表垂直偏移距离??
* @example
* ```javascript
* var location = UE.dom.domUtils.getXY( document.getElementById(&test&) );
* //output: test的坐标为: 12, 24
* console.log( 'test的坐标为??', location.x, ',', location.y );
getXY:function (element) {
var x = 0, y = 0;
while (element.offsetParent) {
y += element.offsetT
x += element.offsetL
element = element.offsetP
return { 'x':x, 'y':y};
* 为元素element绑定原生DOM事件,type为事件类型,handler为处理函??
* @method on
* @param { Node } element 需要绑定事件的节点对象
* @param { String } type 绑定的事件类??
* @param { Function } handler 事件处理??
* @example
* ```javascript
* UE.dom.domUtils.on(document.body,&click&,function(e){
//e为事件对象,this为被点击元素对戏那个
* 为元素element绑定原生DOM事件,type为事件类型,handler为处理函??
* @method on
* @param { Node } element 需要绑定事件的节点对象
* @param { Array } type 绑定的事件类型数??
* @param { Function } handler 事件处理??
* @example
* ```javascript
* UE.dom.domUtils.on(document.body,[&click&,&mousedown&],function(evt){
//evt为事件对象,this为被点击元素对象
on:function (element, type, handler) {
var types = utils.isArray(type) ? type : utils.trim(type).split(/\s+/),
k = types.
if (k) while (k--) {
type = types[k];
if (element.addEventListener) {
element.addEventListener(type, handler, false);
if (!handler._d) {
handler._d = {
var key = type + handler.toString(),index = utils.indexOf(handler._d.els,element);
if (!handler._d[key] || index == -1) {
if(index == -1){
handler._d.els.push(element);
if(!handler._d[key]){
handler._d[key] = function (evt) {
return handler.call(evt.srcElement, evt || window.event);
element.attachEvent('on' + type, handler._d[key]);
* 解除DOM事件绑定
* @method un
* @param { Node } element 需要解除事件绑定的节点对象
* @param { String } type 需要接触绑定的事件类型
* @param { Function } handler 对应的事件处理器
* @example
* ```javascript
* UE.dom.domUtils.un(document.body,&click&,function(evt){
//evt为事件对象,this为被点击元素对象
* 解除DOM事件绑定
* @method un
* @param { Node } element 需要解除事件绑定的节点对象
* @param { Array } type 需要接触绑定的事件类型数组
* @param { Function } handler 对应的事件处理器
* @example
* ```javascript
* UE.dom.domUtils.un(document.body, [&click&,&mousedown&],function(evt){
//evt为事件对象,this为被点击元素对象
un:function (element, type, handler) {
var types = utils.isArray(type) ? type : utils.trim(type).split(/\s+/),
k = types.
if (k) while (k--) {
type = types[k];
if (element.removeEventListener) {
element.removeEventListener(type, handler, false);
var key = type + handler.toString();
element.detachEvent('on' + type, handler._d ? handler._d[key] : handler);
}catch(e){}
if (handler._d && handler._d[key]) {
var index = utils.indexOf(handler._d.els,element);
if(index!=-1){
handler._d.els.splice(index,1);
handler._d.els.length == 0 && delete handler._d[key];
* 比较节点nodeA与节点nodeB是否具有相同的标签名、属性名以及属性??
isSameElement
* @param { Node } nodeA 需要比较的节点
* @param { Node } nodeB 需要比较的节点
* @return { Boolean } 两个节点是否具有相同的标签名、属性名以及属性??
* @example
* &span sty}

我要回帖

更多关于 优酷录屏软件下载 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信