现在首先关闭每个人都给出答案“不要使用内联事件”,让我首先说我没有使用内联事件,我只是想清理其他人编码而不能进入并修复所有代码。
所以,我编写了一个函数来将内联事件转移到jQuery事件,但它部分使用了新的Function()。它有效,但我知道它可以通常清理得更好。
var transferInlineEvents = function(element){
var attributes = $(element).get(0).attributes;
$(attributes).each(function(i){
if (/^on/.test(this.name)) {
var handler = this.name.replace(/^on/, '');
var evt = this.value;
evt = evt.replace('$(this)', "$('#"+$(element).attr('id')+"')");
$(element).on(handler, function(){
var newEvent = (jQuery.support.boxModel) ? new Function([evt]) : evt;
newEvent();
});
$(element).removeAttr(this.name);
}
});
};
这样做,并且基本上可以做到这一点:
<input type="text" name="myinput" id="myinput" onclick="$(this).val('');" value="Enter your name..." />
进入这个:
<input type="text" name="myinput" id="myinput" value="Enter your name..." />
$('#myinput').on('focus', function(){
$('#myinput').val('');
});
我不知道如何不使用新功能,因此它适用于所有浏览器,我不知道如何制作,所以我不需要替换它。
感谢任何帮助。
答案 0 :(得分:3)
这将花费你一些努力,但不会给你买任何东西。
不应用内联事件处理程序的一点是将语义(标记)与页面功能(脚本)分开。另一种是将脚本执行推迟到所有其他页面加载活动发生之后。
在页面加载后开始操作事件处理程序后,这些目标都无法实现。如果你继续使用这种方法,你的源代码中仍然存在混乱(如果你查看源代码我保证你仍会看到内联处理程序),浏览器仍会将这些处理程序附加到DOM中的元素在删除并重新附加它们之前。
真正清理事物的唯一方法是在源代码中,在后端执行此操作。
答案 1 :(得分:0)
根据你的报价:Any help is appreciated.
请注意以下代码,使用eval
,这不是JavaScript编程的一部分,并且已知不安全。
我认为这足够跨浏览器:
var transferInlineEvents = function(element){
var attributes = $(element).get(0).attributes;
$(attributes).each(function(i){
if (/^on/.test(this.name)) {
var handler = this.name.replace(/^on/, '');
var evt = this.value;
evt = evt.replace('$(this)', "$('#"+$(element).attr('id')+"')");
$(element).on(handler, function() {
console.log('event activated', evt);
var newEvent = eval('(function(){'+evt+'});');
newEvent();
});
$(element).removeAttr(this.name);
}
});
};
$("input").each(function(i, element) {
transferInlineEvents(element);
});
您可以找到演示here。
另一种方法,如果你知道你的内联代码很简单而且不那么复杂,那就是regexp检查内联函数的每个参数,并为每个参数创建一个单独的函数。
这通常是安全的,但它不适用于复杂的代码。
var transferInlineEvents = function(element){
var attributes = $(element).get(0).attributes;
$(attributes).each(function(i){
if (/^on/.test(this.name)) {
var handler = this.name.replace(/^on/, '');
var evt = this.value;
var actions = evt.split(';');
var functions = [];
for ( var action = 0; action < actions.length; action++ ) {
var methods = actions[action].split('.');
for ( var method = 1; method < methods.length; method++ ) {
/* If it is val attribute */
if ( /^val\(/.test(methods[method]) ) {
var value = methods[method].substr(4).replace(/^('|")/, '').replace(/\)$/, '').replace(/('|")$/, '');
functions.push( function() { $('#'+element.id).val(value) } );
}
}
}
if ( functions.length > 0 ) {
$(element).on(handler, function() {
for ( fn = 0; fn < functions.length; fn++ ) {
console.log('fireing up function');
functions[fn]();
}
});
$(element).removeAttr(this.name);
}
}
});
};
答案 2 :(得分:0)
经过大量阅读和搜索后,如果不使用eval()或新的Function(),似乎无法做到这一点。而且由于后者稍微好一些,我会继续这样做。另外,请记住,eval()和new Function()只有当它们是可由用户操作的输入的一部分时才是不安全的。在我的情况下情况并非如此,所以我认为这是安全的。
这会将带有'on'前缀的所有内联事件转换为jQuery绑定事件并删除内联事件。
;(function ($) {
$.fn.transferInlineEvents = function () {
var el = this;
var attributes = el.get(0).attributes;
$(attributes).each(function(i){
var oEvent = this.name;
var oFunc = $.trim(this.value);
if (/^on/.test(oEvent)) {
var nEvent = oEvent.replace(/^on/, '');
var nFunc = new Function(oFunc);
el.removeAttr(oEvent);
el.bind(nEvent, nFunc);
}
});
};
})(jQuery);