简体   繁体   English

javascript onclick事件,同一元素的每次点击具有不同的功能

[英]javascript onclick event, different function for each click of same element

I am attempting to create an onclick function which has 1 of 2 outcomes on each click. 我正在尝试创建一个onclick函数,该函数在每次单击中具有2个结果中的1个。 In other words, when the user clicks the onclick element for the first time the outcome 1 occurs; 换句话说,当用户第一次单击onclick元素时,结果1发生; then the user clicks the same element a second time, outcome 2 occurs. 然后用户再次单击相同的元素,就会出现结果2。 When the user clicks on the element a third time, outcome 1 happens again; 当用户第三次单击该元素时,结果1再次发生; forth click, outcome 2 occurs; 第四次点击,结果2发生; and so on, like a loop. 等等,就像一个循环。 Below is some pseudo jQuery to give an illustration... 下面是一些伪jQuery的说明...

$(function(){
            var hits = 0;
    $('#myButton').click(function(){
                    if  (var hits = pos ) 
                    {
              $('#content1').fadeIn("slow");
              $('#content2').fadeOut("slow");
                    }
                    else
                    {
              $('#content1').fadeOut("slow");
              $('#content2').fadeIn("slow");
                    }
        return false;
    });
});

I have had a hard time searching for an answer because the terminology can vary tremendously. 我很难找到答案,因为术语可能千差万别。 From 'variable' to 'trigger' to 'array' to 'listener' to 'handler' to 'conditional' to 'bind'.... where do I begin to search? 从“变量”到“触发”再到“数组”再到“侦听器”再到“处理程序”再到“有条件的”再到“绑定”。...我应该从哪里开始搜索? I know there are multiple ways to create my function, but I know this is the best site to go to find the easiest, most efficient way. 我知道有多种创建函数的方法,但是我知道这是查找最简单,最有效方法的最佳站点。 So on top of helping me out syntactically, I'd also like some terminology help with the cluster of words I listed. 因此,除了在句法上帮助我之外,我还希望一些关于列出的单词的术语帮助。 I know the general meaning of each term, but when applying them to the scenario/function I am trying to create, where do they each play a part? 我知道每个术语的一般含义,但是将它们应用于我要创建的场景/功能时,它们各自在哪里发挥作用? I think this will help straighten things out for a lot of people. 我认为这将帮助许多人理顺事情。 Thanks in advance. 提前致谢。

Thank you all for the quick and elaborate, professional feedback. 谢谢大家的迅速详尽的专业反馈。 I will use this new knowledge to its advantage. 我将利用这一新知识来发挥其优势。 JQuery really does make things simple, almost too easy. jQuery确实使事情变得简单,几乎太简单了。 However, the main reason I asked this question was to apply it to a keydown function, instead of a click function. 但是,我问这个问题的主要原因是将其应用于键按下功能,而不是单击功能。 I thought I could find an answer and swap some code around, maybe with normal javascript this would have worked. 我以为我可以找到答案并交换一些代码,也许使用普通的javascript可以解决。 I have posted a new question that uses the knowledge and feedback you all have provided and come up with a different scenario involving the keydown function. 我发布了一个新问题,该问题使用了大家提供的知识和反馈,并提出了涉及keydown功能的不同方案。 I think I have the syntax pretty close thanks to your help, but however, only almost. 我想我的语法非常接近,这要归功于您的帮助,但是几乎可以。 If you would like to see, here is the url : bind event handler on keydown listen function JavaScript jQuery You guys truly rock. 如果您想看的话,这里是urlkeydown监听函数JavaScript jQuery上的bind事件处理程序 你们真的很摇滚。

jQuery has .toggle(handlers) for alternating clicks functionality: jQuery具有.toggle(handlers)用于交替单击功能:

$('#myButton').toggle(function() {
    $('#content1').fadeIn("slow");
    $('#content2').fadeOut("slow");
}, function() {
    $('#content1').fadeOut("slow");
    $('#content2').fadeIn("slow");
});

Fiddle 小提琴

Now if all you want to do is switch 2 elements by fading them in/out respectively, you can use .fadeToggle() : 现在,如果您只想通过分别淡入/淡出2个元素来切换它们,则可以使用.fadeToggle()

$('#myButton').click(function() {
    $('#content1, #content2').fadeToggle("slow");
});

Fiddle 小提琴

As you want to know some terminology etc. I will provide you with some language-independent one. 您可能想知道一些术语等。我将为您提供一些与语言无关的术语。

Basically, I would call your requirement a 'state machine'. 基本上,我将您的需求称为“状态机”。

In it's very basic, a state machine contains of "states", "events", and "transition functions". 从根本上讲,状态机包含“状态”,“事件”和“转换函数”。 In your case you've got 2 states (let's call them "visible" and "hidden"), one event ("click") and 2 transition functions (we can call them "showContentOne" and "showContentTwo"). 在您的情况下,您有2个状态(我们称它们为“可见”和“隐藏”),一个事件(“单击”)和2个转换函数(我们可以将它们称为“ showContentOne”和“ showContentTwo”)。

Two clarify terminology: 有两个明确的术语:

  • a state is your memory (it tells you what has happened in the past) 状态是您的记忆(它告诉您过去发生的事情)
  • an event is any external activity which will cause the change of state 事件是将导致状态改变的任何外部活动
  • a transition function is a function, called when state-changing event occurs with a goal to change (or "transit") a state from one to another (possibly executing some side-effects). 转换函数是一种功能,在发生状态更改事件时调用,目的是将状态从一个状态更改为另一个状态(可能执行某些副作用)。

Following, I will provide you with very basic (too basic in fact) explanation of concept, but keep in mind that I oversimplify things here - read appropriate articles in books or even wikipedia to get more precise information. 接下来,我将为您提供概念的非常基本的说明(实际上太基本了),但请记住,我在这里过于简化了-阅读书籍甚至Wikipedia中的适当文章以获得更精确的信息。

A state machine can be best described with a graph, in your case: 在您的情况下,最好使用图形来描述状态机:

状态机图

So how to implement this thing properly? 那么如何正确实现呢?

you must have some variable to store state of your element. 您必须具有一些变量来存储元素的状态。 In your code snippet you have used global variable called "hits". 在您的代码段中,您使用了名为“ hits”的全局变量。 As you use jQuery I would instead use it's "data" function which let's you bind arbitrary data to your DOM element (this way you will be able to install many independent state machines in single DOM tree). 当您使用jQuery时,我会改用它的“数据”功能,该功能使您可以将任意数据绑定到DOM元素(这样,您就可以在单个DOM树中安装许多独立的状态机)。 Then you need to bind event handlers (this is easy as you have only one event to consider - click) and define your state transition functions. 然后,您需要绑定事件处理程序(这很容易,因为您只需要考虑一个事件-单击)并定义状态转换函数。 Finally you need a function that will check state of an element, analyse incoming event and call appropriate state transition function. 最后,您需要一个函数来检查元素的状态,分析传入事件并调用适当的状态转换函数。

Some basic implementation could look like this (I will not test this code, treat it as pseudo-code to help you get executable solution) 一些基本的实现可能看起来像这样(我不会测试此代码,将其视为伪代码以帮助您获得可执行的解决方案)

function showContentOne($element) {
     $('#content1').fadeIn("slow");
     $('#content2').fadeOut("slow");
     $element.data('state', 'hidden');
}

function showContentTwo($element) {
     $('#content1').fadeOut("slow");
     $('#content2').fadeIn("slow");         
     $element.data('state', 'visible');
}

function transitState($element, event) {
     var state = $element.data('state');
     if (state == 'visible' && event == 'click') {
          showContentTwo($element);
     } else if (state == 'hidden' && event == 'click') {
          showContentOne($element);
     } else {
          //unsupported transition - do nothing or raise error
     }
}

$(function(){
    $('#myButton')
        .data('state', 'visible') //initialize a state
        .click(function() { //install event handler
          transitState($(this), 'click');
        }
        //here you can possibly install more event handlers
    });
});

Now if you reimplement "transitState" to use some array or objects like state machine definition you can get quite robust solution to add/remove events and other state transition functions. 现在,如果重新实现“ transitState”以使用某些数组或对象(如状态机定义),则可以获得相当强大的解决方案来添加/删除事件和其他状态转换函数。 You can install a state machine on any element, perhaps wrap this with jquery plugin. 您可以在任何元素上安装状态机,也可以用jquery插件包装它。

Note: in your case my solution is serious over-engineering of this task. 注意:在您的情况下,我的解决方案是对该任务进行认真的过度设计。 I provided it to give you some terminology. 我提供它是为了给您一些术语。 Your very basic problem (2 states, 2 transitions, one event) can be easily implemented in very similiar way you showed in original question, only change I would make is not using global variable, but data function to maintain state. 您的非常基本的问题(2个状态,2个转换,一个事件)可以很容易地以您在原始问题中显示的方式来实现,只是我要做的更改不是使用全局变量,而是使用数据函数来保持状态。 Because you have got exactly two states, boolean variable to hold it will be perfectly fine. 因为您刚好有两个状态,所以将其保存为布尔变量就可以了。

$(function(){

$('#myButton')
    .data('isVisible', true)
    .click(function(){
         if  ($(this).data('isVisible')) { 
              $('#content1').fadeIn("slow");
              $('#content2').fadeOut("slow");
         } else {
              $('#content1').fadeOut("slow");
              $('#content2').fadeIn("slow");
         }
         $(this).data('isVisible', !$(this).data('isVisibile'));
         return false;
    });
});

And as others stated for changing visibility of elements on consecutive clicks you can use toggle functions. 正如其他人指出的那样,在连续单击时更改元素的可见性,您可以使用切换功能。

sorry for my poor english :/ 对不起,我的英语不好:/

Try: 尝试:

$(function(){
            var hits = 0; //->variable
    // Everything below this line is called "binding" a handler to an event (click event)
    $('#myButton').click(function(){ // --> This whole function is the handler or listener
                    if  (hits % 2 !== 0) //for hits 2,4,6,8 etc. Also the condition
                    {
              $('#content1').fadeIn("slow");
              $('#content2').fadeOut("slow");
                    }
                    else
                    { // for hits 1,3,5,7
              $('#content1').fadeOut("slow");
              $('#content2').fadeIn("slow");
                    }
                   hits++;
        return false;
    });
});

May I suggest you have a look into jQuery's toggle() method which would be used like: 我可以建议您看看jQuery的toggle()方法,该方法的用法如下:

$(function() {
    $('#myButton').toggle(function(){...}, function(){...});
});

I also give you a modified version of the DIY way: 我还为您提供了DIY方法的修改版本:

$(function(){
    var hits = 0;

    $('#myButton').click(function(){
        hits ^= 1;

        if  ( hits ) {
            $('#content1').fadeIn("slow");
            $('#content2').fadeOut("slow");
        } else {
            $('#content1').fadeOut("slow");
            $('#content2').fadeIn("slow");
        }

        return false;
    });
});

One way to easily achieve this, and perhaps make it somewhat more elegant, would be to write this simple plugin: 轻松实现这一目标(也许使其更优雅)的一种方法是编写以下简单插件:

(function ($) {
    $.fn.rollerClick = function (handlers) {
        this.each(function () {
            this.hits = 0;
            $(this).click(function () {
                handlers[this.hits ++](this);
                if (this.hits == handlers.length) {
                    this.hits = 0;
                }
            }); 
        });
    };
)(jQuery);

Now you can use it like this: 现在您可以像这样使用它:

$("selector").rollerClick([
    function (element) {
        alert('1');
    },
    function (element) {
        alert('2');
    },
    function (element) {
        alert('3');
    }
]);           

Then by clicking repeatedly over the selected item you will roll through the handlers, seeing alerts popping up showing "1", "2", "3", "1", "2", ... . 然后,通过反复单击所选项目,您将滚动处理程序,看到弹出的警报显示“ 1”,“ 2”,“ 3”,“ 1”,“ 2”,...。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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