简体   繁体   中英

Using css selectors as inputs for javascript

So far I'm using different buttons for different transitions (each one with individual function) on one DOM element :

onButtonClickUp = function(){
    document.querySelector('.cube-rot').style.transform="rotateY(90deg)"
    };
onButtonClickDown = function(){
    document.querySelector('.cube-rot').style.transform="rotateY(-90deg)"
};
onButtonClickRight = function(){
    document.querySelector('.cube-rot').style.transform="rotateX(90deg)"
};
onButtonClickLeft = function(){
    document.querySelector('.cube-rot').style.transform="rotateX(-90deg)"
};
document.querySelector('.show-up').addEventListener( 'click', onButtonClickUp, false);
document.querySelector('.show-down').addEventListener( 'click', onButtonClickDown, false);
document.querySelector('.show-left').addEventListener( 'click', onButtonClickLeft, false);
document.querySelector('.show-right').addEventListener( 'click', onButtonClickRight, false);

I'm firing everything off on DomContentLoaded and it's working, but I'd like to combine the functions into one with different cases;


this is what I've tried

 function onButtonClick(rot){
    //rot = rUp || rDown|| rLeft ||rRight ;
    if(rot == 'rUp'){rot = "rotateY(90deg)";}
    else if (rot == 'rDown'){ rot = "rotateY(90deg)"}
    else if (rot == 'rLeft'){ rot = "rotateX(90deg)"}
    else if(rot == 'rRight' ){ rot = "rotateX(-90deg)"};

    cubeRot.style.transform=rot
    };


 document.querySelector('.show-up').addEventListener( 'click', onButtonClick('rUp'), false);
 document.querySelector('.show-down').addEventListener( 'click', onButtonClick('rDown'), false);
 document.querySelector('.show-right').addEventListener( 'click', onButtonClick('rRight'), false);
 document.querySelector('.show-left').addEventListener( 'click', onButtonClick('rLeft'), false);

it doesn't work, adding different EventListners resolves in the last overriding previous.. what's the most convenient way to do this?

Since you are calling onButtonClick() when you do your event binding, it needs to return a function.

function onButtonClick(rot){
    return function(e) {
        //rot = rUp || rDown|| rLeft ||rRight ;
        if(rot == 'rUp'){rot = "rotateY(90deg)";}
        else if (rot == 'rDown'){ rot = "rotateY(-90deg)"}
        else if (rot == 'rLeft'){ rot = "rotateX(90deg)"}
        else if(rot == 'rRight' ){ rot = "rotateX(-90deg)"};

        cubeRot.style.transform=rot;
    };
}

Alternatively, leave the function as is and use .bind() :

document.querySelector('.show-up').addEventListener('click', onButtonClick.bind(null, 'rUp'), false);
document.querySelector('.show-down').addEventListener('click', onButtonClick.bind(null, 'rDown'), false);
document.querySelector('.show-right').addEventListener('click', onButtonClick.bind(null, 'rRight'), false);
document.querySelector('.show-left').addEventListener('click', onButtonClick.bind(null, 'rLeft'), false);

The above solutions should get you unblocked. But, there are some more code improvements you could consider.

Instead of that long if .. else if block, you could store the value in an object and look up the value by a key:

var rotations = {
    rUp: "rotateY(90deg)",
    rDown: "rotateY(-90deg)",
    rLeft: "rotateX(90deg)",
    rRight: "rotateX(-90deg)"
};
function onButtonClick(rot) {
    cubeRot.style.transform = rotations[rot];
}

Your event handler has access to the clicked element via this . You don't need to pass a rot argument, you can just look at this.className :

var rotations = {
    up: "rotateY(90deg)",
    down: "rotateY(-90deg)",
    left: "rotateX(90deg)",
    right: "rotateX(-90deg)"
};
function onButtonClick(e) {
    var rot = this.className.slice(5);
    cubeRot.style.transform = rotations[rot];
}
[].slice.call(document.querySelectorAll("[class^='show-']")).forEach(function(el) {
    el.addEventListener("click", onButtonClick, false);
});

Assuming your buttons are plain HTML buttons with no innerHTML you can do this

<input type="button" action-type="rUp" value="Show up" class="show-up" />

This adds an attribute to the input with the desired action variable.

function onButtonClick(e){
    var rot = e.target.getAttribute("action-type");
    if(rot == 'rUp'){rot = "rotateY(90deg)";}
    else if (rot == 'rDown'){ rot = "rotateY(90deg)"}
    else if (rot == 'rLeft'){ rot = "rotateX(90deg)"}
    else if(rot == 'rRight' ){ rot = "rotateX(-90deg)"};

    cubeRot.style.transform=rot;
    };


 document.querySelector('.show-up').addEventListener( 'click', onButtonClick, false);
 document.querySelector('.show-down').addEventListener( 'click', onButtonClick, false);
 document.querySelector('.show-right').addEventListener( 'click', onButtonClick, false);
 document.querySelector('.show-left').addEventListener( 'click', onButtonClick, false);

When the event is fired e.target refers to the element that fired the event (the button). rot stores the attribute action-type . Based upon rot the correct action will be applied. The advantage is that this doesn't require new functions to be created or functions to be wrapped in a bind.

You can use the this object to reference the button that's triggering the event:

  var onButtonClick = function () {
    var button = this;
    document.querySelector('.dir').innerHTML = button.name;
    switch(button.name) {
       case 'up': alert('up'); break;
       case 'down': alert('down'); break;
       case 'left': alert('left'); break;
       case 'right': alert('right'); break;
     }
  };

  document.querySelector('.show-up').addEventListener('click', onButtonClick, false);
  document.querySelector('.show-down').addEventListener('click', onButtonClick, false);
  document.querySelector('.show-left').addEventListener('click', onButtonClick, false);
  document.querySelector('.show-right').addEventListener('click', onButtonClick, false);

Check this plunk: http://plnkr.co/edit/MJzMffnDZJripzXkiZzc

Happy coding!

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