0

现在首先在每个人给出答案“不要使用内联事件”之前让我先说我没有使用内联事件,我只是想清理其他人编码的内容而无法进入并修复所有的代码。

因此,我编写了一个小函数来将内联事件转换为 jQuery 事件,但它部分使用了 new 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('');
});

我不知道如何不使用 new Function 所以它适用于所有浏览器,我不知道如何制作它,所以我不需要替换它。

任何帮助表示赞赏。

4

3 回答 3

3

这将花费你很多努力,但不会给你带来任何好处。

不内联应用事件处理程序的一点是保持语义(标记)与页面功能(脚本)分开。另一种是将脚本执行推迟到所有其他页面加载活动发生之后。

一旦您在页面加载后开始操作事件处理程序,这些目标都无法实现。如果您继续使用这种方法,您的源代码中仍然存在混乱(我保证,如果您查看源代码,您仍然会看到内联处理程序)并且浏览器仍然会将这些处理程序附加到 DOM 中的元素,然后再删除并重新连接它们

真正清理事情的唯一方法是在后端的源代码中进行。

于 2013-05-07T06:23:51.230 回答
0

按照您的报价:Any help is appreciated.

选项一

请注意下面的代码 uses 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);
});

你可以在这里找到一个演示。

选项二

另一种方法,如果你知道你的内联代码很简单而且不那么复杂,那就是正则表达式检查你的内联函数的每个参数,并为每个参数创建一个单独的函数。

这通常是安全的,但它不适用于复杂的代码。

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);
          }
        }
    });

};

演示:http: //jsbin.com/osevop/1/edit

于 2013-05-07T06:17:53.587 回答
0

经过大量阅读和搜索后,似乎没有使用 eval() 或 new 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);

在这里测试它:http: //jsfiddle.net/9vXtm/2/

于 2013-05-07T16:13:13.633 回答