简体   繁体   中英

How can I remove only one attribute value and not another with jQuery?

So I have found all over stackoverflow how to remove an entire attribute, however I only want to remove the first value of an onClick attribute but not the second. All my different instances of each container have a unique function associated to them and they all share the first function in common... Once any of these containers are clicked, the first function needs to be gone but I need to retain the second without altering it at all. My code follows:

<div class="halves marginal" onClick="buildFrame(),viscalc()">
<div class="two_one marginal" onClick="buildFrame(),percentOf()">

etc etc

Once buildFrame() executes once:

function buildFrame(){
document.getElementById('screenframe').innerHTML = "<img src='img/screen.png'><iframe id='framecontent'>";

I would like to remove it from each class ( but keep percentOf(), viscalc() etc etc )

How can I remove only one attribute value and not the other?

so this is what i would do.

$("div.marginal").on("click", function(){
   $(this).off("click", buildFrame);
});

that removes it from the event queue for the functions listener.

You cant do it with anon functions.

idea:

$("div.marginal").on("click", function(){ 
    var funcs = $(this).attr("onclick").split(",");
    $(this).attr("onclick", funcs[1]);
    console.log("value of 'onclick'", $(this).attr("onclick"));

    // or alternatively

    $(this).off("click", funcs[0].substr(0,funcs[0].length-2))
    //this breaks apart the onclick, turns off the click event for event0, while maintaining
    //   the second event.
});

the issue that i can see, from my point of view is that since it is inline, it really executes it once, so changing onclicks value might not be enough as it might not be refreshed. The above jquery though, will do what your case would want.

I think the most pin-pointed approach to this would be pass this in your buildFrame and then inside the buildFrame remove itself from the calling object.

<div class="halves marginal" onClick="buildFrame(this),viscalc()">


function buildFrame(obj){
    document.getElementById('screenframe').innerHTML = "<img src='img/screen.png'><iframe id='framecontent'>";
    // not sure why your not closing the iframe tag ill assume you wanted it this way
    $( this ).off("click", buildFrame);
};

** EDIT **

Missed your edit where you want to remove it from all instances, this complicates it much, this solution is no longer viable.

Fairly straightforward to do with a custom selector. I think this can be done without the eval() but I'm not sure how offhand.

Here you go:

HTML

<div class="halves marginal" onClick="buildFrame();viscalc();"></div>
<div class="two_one marginal" onClick="buildFrame();percentOf();"></div>

Javascript

$.expr[':'].hasFrameMethod = function(obj){
  var onClick = $(obj).attr('onClick');  
  return onClick != undefined ? onClick.split(';').indexOf("buildFrame()") != -1 : false;   
};

function buildFrame(){
    document.getElementById('screenframe').innerHTML = "<img src='img/screen.png'><iframe id='framecontent'>";      

    $('div:hasFrameMethod').each(function(idx, item){
        htItem = $(item);
        var itemClickFns = htItem.attr('onClick') != undefined ? htItem.attr('onClick').split(';') : (htItem.attr('onclick') != undefined ? htItem.attr('onclick').split(';') : "");
        htItem.attr('onClick', '');
        htItem.attr('onclick', '');
        htItem.off("click");

        // re-add any correct secondary actions
        if(itemClickFns.length > 1){

            var strFnClick = "function onclick(event) { ";

            itemClickFns.forEach(function(elem,idx){
                if(elem != "buildFrame()"){
                    if(elem.length > 0){
                        strFnClick += elem + ";";
                        htItem.attr('onclick', htItem.attr('onclick') + elem + ";");
                    }
                }                               
            });

            strFnClick += "}";

            // Rebind the event
            htItem.prop('onclick', eval(strFnClick));
            htItem.click(eval(strFnClick));
        }
    });
}

As long as this code loads after jQuery it should work. :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM