0

次のようなjQueryセレクターを指すように変数を設定するという厄介な問題が発生しています。var foobar=jQuery(this);次に、この変数を作業対象の関数に渡します。少し単純化して、関数が次のようになっているとしましょう。

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

この状況では、次のことを想定しています。

  • セレクターは常にフォーム要素です(したがって、val()は有効な操作です)
  • セレクターは、「id」属性を持つ単一のdom要素に解決されます

次に、2つの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

Lets examine the code a bit.

First assigning back to a parameter is not a good practice adding a var at the start of your function would be a lot better, as scope can be lost.

//Suggestion change parameter to domItem
var domObject

Your missing an error handler for when the parameter is not String. when identifying the type use

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

It's more efficient and handles custom types.

No need for all the logic in assignment of value attribute. Any dom Object can be made to have a value attribute. also not sure why you are setting the val versus the value.

domObject.attr('value',value);

It is at this point that I can see your code could really use some documentation to help explain purpose

If you are explicitly only wanting to set value on Input fields and set value as innerhtml on non input fields then yes the logic would be needed but could be simplified to ... as the value doesn't need to be detected to overwritten.

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

No Idea why you are returning the domObject out.

So a quick rewrite without the return and keeping most of the logic adding error handling results in

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

The above passes JSLint

于 2012-12-05T18:54:01.640 に答える
0

人々がこの問題を実際に掘り下げるのに十分なコンテキストを提供しなかったことはわかっていますが、最終的には解決しました。問題は何でしたか?最初に尋ねたのは @Kobi で、DOM 要素の ID は一意でした...私は喜んでそれを報告しました。そして、それはそうでしたが、実際にはそれが問題でした. イエス。トラブルに巻き込まれるのは、見落としがちな明らかなことです。

とにかく、あなたの忍耐と助けに感謝します。

于 2012-12-04T16:34:42.070 に答える