What is the javascript equivalent to jquery closes

2020-04-23 02:45发布

I have the following code, which is written in DOM API instead of jquery. I'm not sure why. It's inside the submit function for jquery form validation. I need to change the "parentNode" part so that instead of "parent" it is "closest." I'm no good with javascript. I tried my hand at converting this to jquery, but wasn't able to get that to work. Basically, if this were jquery, I'd need to change .parent() to .closest().

var summary = "";

$.each(element, function() { 
summary += "<li>" + this.element.parentNode.getElementsByTagName('label')[0].innerHTML.replace("\<span\>*\<\/span\>","") + "</li>"; 
});

summary = summary.replace(/\<li\>.+\<\/li\>\1/, "$1");

alert(summary);

Is this possible to do with javascript? Or, is there an easy way to convert this to jquery?

UPDATE: Here is a fiddle to help explain what I'm trying to accomplish. Basically, because I added a 'span' tag around one of the inputs, the 'p' tag is no longer the parent. As such, the parentNode is not finding the 'p' tag anymore.

http://jsfiddle.net/9um8xt79/1/

UPDATE 2 -- THE previous fiddle link was incorrect. The link above is the right one.

How can I modify to find the <p> tag regardless of whether it is the direct parent, or a grandparent?

4条回答
虎瘦雄心在
2楼-- · 2020-04-23 03:09

Reading your question carefully, I think you want something like

var summary = "";
$(element).each(function (id, ele) {
    summary +=  "<li>" + $(ele).closest("label").html().replace("\<span\>*\<\/span\>","") + "</li>";
});

summary = summary.replace(/\<li\>.+\<\/li\>\1/, "$1");

But I'm not sure what you're doing with this last line. First you add all the label-Elements as li-Elements and then you remove all those li-s? But I'm not really a RegExp profi so I might miss something here.

查看更多
SAY GOODBYE
3楼-- · 2020-04-23 03:21

Hello from the future (2019)! This is now directly possible with native DOM API in modern browsers (that is, not Internet Explorer): Element.closest

So you can replace jQuery(selector).closest with document.querySelector(selector).closest.

Similarly, you should be able to eliminate other jQuery functions in your code such as .children() by using native .children and .addClass() by using .classList.add().

See also

查看更多
够拽才男人
4楼-- · 2020-04-23 03:23

Maybe I'm a bit late ;-) but here is a simple recursive function (calls it self with the parentNode to be analised) in plain old JS:

function closest( e, classname ) {
    if( hasClass( e, classname ) ) {
        //We found it!
        return e;
    }
    //console.error(e.parentNode.nodeName);
    if(e.parentNode.nodeName != 'BODY') //Last possibility! There's no parent behind!
        return e.parentNode && closest( e.parentNode, classname );

    //Didn't found it?
    return null;
}

hasClass() function (the equivalente to JQuery hasClass()) depends on the browser knowing classList - as in nowadays is almost the case.

But, anyway, here it goes for both older and (the so called) newer browsers:

var
    hasClass

;
if ( 'classList' in document.documentElement ) {
    hasClass = function( elem, c ) {
        return elem.classList.contains( c );
    };
}
else {
    hasClass = function( elem, c ) {
        return classReg( c ).test( elem.className );
    };
}

As notice, for older browsers, we use a RegExp to string comparision.
Here it is (and, promisse, final stuff :-) ):

function classReg( className ) {
    return new RegExp("(^|\\s+)" + className + "(\\s+|$)");
}

And that's it.
Now it's explained, if anyone uses the complete set of "tools", off course you have to code it down the inverse way (1st classReg(), then hasClass stuff and final our closest() queen).

Also, if you noticed, you gain here 2 equivalente JQuery tools (closest() and hasClass()) that you can use in multiple situations - as I use them for several years, now:
hasClass( elem, 'my-class-to-check' ) //<= returns true || false
closest( elem, 'my-class-to-look-up' ) //<= returns the look-up obj || null

查看更多
再贱就再见
5楼-- · 2020-04-23 03:29

Here's the javascript for the .closest property:

closest: function( selectors, context ) {
        var cur,
            i = 0,
            l = this.length,
            matched = [],
            pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
                jQuery( selectors, context || this.context ) :
                0;

        for ( ; i < l; i++ ) {
            for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
                // Always skip document fragments
                if ( cur.nodeType < 11 && (pos ?
                    pos.index(cur) > -1 :

                    // Don't pass non-elements to Sizzle
                    cur.nodeType === 1 &&
                        jQuery.find.matchesSelector(cur, selectors)) ) {

                    matched.push( cur );
                    break;
                }
            }
        }

Whenever you're trying to figure out something is done in jQuery, you can always just take a look at the jQuery source and reverse engineer it to your scenario. Although there will be times when this won't work, the way your question is phrased, this is where I'd start.

Source: http://code.jquery.com/jquery-2.1.1.js

查看更多
登录 后发表回答