0

我遇到了一个令人抓狂的问题,我将一个变量设置为指向一个 jQuery 选择器,例如:var foobar=jQuery(this);然后我将此变量传递给一个要处理的函数。让我们稍微简化一下,说函数看起来像这样:

function SetFieldValue (selector) {
  selector.val('test');
  console.log ( selector );
  console.log ( jQuery('#' + selector.attr('id')) );
}

在这种情况下,如果您假设:

  • 选择器始终是一个表单元素(因此 val() 是一个有效的操作)
  • 选择器确实解析为具有“id”属性的单个 dom 元素

然后,您会期望两个 console.log 语句输出相同的结果,对吗?好吧,我遇到了这种情况仅在大约 90% 的情况下发生的情况。

为了提供更多上下文,我创建了一个简短的截屏视频来演示该问题:

截图链接

出于参考目的,以下是截屏视频中显示的实际 SetFieldValue 代码:

function SetFieldValue ( domObject, value ) {
// as a safety function, check if a string representation of the domObject was passed in and convert it to a jQuery object if it was
if ( jQuery.type(domObject) === "string") {
    console.log ("Value passed into SetFieldValue was a string representation so converting to jQuery object");
    domObject = jQuery(domObject);
}

if ( jQuery.inArray (domObject.prop('tagName').toLowerCase(),['input' , 'select' , 'textarea']) >= 0 ) {
    console.log ("setting to value attribute: " + value);
    if ( domObject.hasAttr('id') ) {
        domObject.val(value);
        //jQuery('#' + domObject.attr('id')).val(value);
    } else {
        domObject.attr('value',value);          
    }

    console.log ("Using jQuery ID it is set to: " + jQuery('#' + domObject.attr('id')).val() );
    console.log ("Using jQuery selector variable it is set to: " + domObject.val() );
} else {
    console.log ("setting to html attribute");
    domObject.html( value );
}
return domObject;
}
4

2 回答 2

1

让我们稍微检查一下代码。

首先分配回参数不是一个好习惯,在函数开头添加 var 会好很多,因为可能会丢失范围。

//Suggestion change parameter to domItem
var domObject

当参数不是字符串时,您缺少错误处理程序。识别类型时使用

<VARNAME>.constructor.toString().match(/function (\w*)/)[1] === "<TYPE>"

它更高效并处理自定义类型。

不需要值属性分配的所有逻辑。可以使任何 dom 对象具有 value 属性。也不确定为什么要设置 val 与 value。

domObject.attr('value',value);

正是在这一点上,我可以看到您的代码确实可以使用一些文档来帮助解释目的

如果您明确地只想在输入字段上设置值并在非输入字段上将值设置为 innerhtml,那么是的,逻辑将是必需的,但可以简化为 ... 因为不需要检测到覆盖该值。

if (jQuery.inArray (domObject.prop('tagName').toLowerCase(), ['input' , 'select' , 'textarea']) >= 0) {
    domObject.attr('value',value);
} else {
    domObject.html( value );
}

不知道为什么要返回 domObject 。

因此,无需返回并保留大部分逻辑添加错误处理的快速重写会导致

/*jslint sloppy: true*/
/*global jQuery*/
function SetFieldValue(domString, value) {
    // as a safety function, check if a string representation of the domObjects was passed in and convert it to a jQuery object if it was
    var domObjects, index;
    //errorhandling
    if (domString === undefined || domString === null) {
        throw {error : "domString must have a value."};
    }
    if (domString.constructor.toString().match(/function (\w*)/)[1] !== "string") {
        if (domString.constructor.toString().match(/function (\w*)/)[1].match(/HTML[a-zA-Z]*Element/) === null) {
            throw {error : "domString expected to be String or domObjects"};
        }
    } else {
        if (jQuery(domString).length === 0) {
            throw {error : "domString does not resolve to a detectable domObjects."};
        }
    }
    //errorhandling

    //action
    if (domString.constructor.toString().match(/function (\w*)/)[1].match(/HTML[a-zA-Z]*Element/)) {
        //made as an array to normalize as jQuery returns an array allows code to be simplified
        domObjects = [domString];
    } else {
        domObjects = jQuery(domString);
    }

    //given that domObjects are an array need to step through the array
    for (index = domObjects.length - 1; index >= 0; index -= 1) {
        if (
            jQuery.inArray(
                domObjects[index].tagName.toLowerCase(),
                ['input', 'select', 'textarea']
            ) >= 0
        ) {
            if (domObjects[index].hasAttr('id')) {
                domObjects[index].val(value);
            } else {
                domObjects[index].attr('value', value);
            }
        } else {
            domObjects[index].html(value);
        }
    }
}

以上通过 JSLint

于 2012-12-05T18:54:01.640 回答
0

我知道我没有为人们提供足够的背景来真正深入研究这个问题,但我最终解决了它。问题是什么?好吧,是@Kobi 首先询问 DOM 元素的 ID 是否唯一……我很高兴地向其报告。事实上,这就是问题所在。耶稣。总是让你陷入困境的那些显而易见的事情会被你忽略。

无论如何,感谢您的耐心和帮助。

于 2012-12-04T16:34:42.070 回答