Programmatically Click on Label/Radio or Fire Event

随声附和 提交于 2019-12-11 17:16:37

问题


I'm writing a userscript that injects a custom javascript into the head of a page. Easy peasy

// ==UserScript==
// @name    *** (BLOCKED DUE TO NDA)
// @namespace   *** (BLOCKED DUE TO NDA)
// @description *** (BLOCKED DUE TO NDA)
// @include *** (BLOCKED DUE TO NDA)
// @author  Aaron K. Henderson
// @version 1.0
// ==/UserScript==

var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.type= 'text/javascript';
script.src= '***.js';
head.appendChild(script);

The .js I inject makes use of the jQuery already being used on the page to make some css changes as well as automate some mundane tasks.

$(document).ready(function() {
    // Rename Approve All Button
    $('#approve-all-button span').text('Scan + Detect');

    // The Magic
    $('#approve-all-button').click(function(i) { 
        var Current_Name = '';
        // Loop through TR
        $('tr').each(function(i) {
            if (i > 0) {

                // Get Current Username in Loop
                Current_Name = $(this).children('.username').text();
                // Apply Default Color to All (Green)
                $(this).css('background-color', '#0AFE47');
                // Apply Approved Class to All
                $(this).addClass('AddApproved');
                // Hide Creation Date / Last Login
                $(this).children('.nowrap').css('opacity','.1').css('background-color','white');
                // Get Current Username Length
                var nlen = Current_Name.length;

                // If Name Length is <= 3 or >= 15 Apply Color (Red)
                if (nlen <= 3) {
                    $(this).css('background-color','#FF7575');
                    $(this).addClass('AddDeleted');
                    $(this).removeClass('AddApproved');
                    $(this).removeClass('AddInactive');         
                }
                if (nlen >= 15) {
                    $(this).css('background-color','#FF7575');
                    $(this).addClass('AddDeleted');
                    $(this).removeClass('AddApproved'); 
                    $(this).removeClass('AddInactive'); 
                }

                var nDigits = 0;
                for ( var t=0; t<nlen; t++) {
                    var chr = Current_Name.charAt(t);
                    if (chr >= "0" && chr <= "9") nDigits++;
                }
                var charcount = nlen - nDigits;

                if ((nDigits >=6) || (charcount < 3) || (nDigits == nlen))  { 
                    $(this).css('background-color','#FF7575');
                    $(this).addClass('AddDeleted');
                    $(this).removeClass('AddApproved');
                    $(this).removeClass('AddInactive'); 
                }
            }
        });
    });
        // On Button Click, Change Background and Add/Remove class
        $('label').click(function(i) {
            var button = $(this).attr('for');
            var status =  button.substring(button.lastIndexOf('-') + 1);
            if (status == 'status_D') {
                $(this).closest('tr').css('background-color','#FF7575');
                $(this).addClass('AddDeleted');
                $(this).removeClass('AddApproved');
                $(this).removeClass('AddInactive');
            } else if (status == 'status_A') {
                $(this).closest('tr').css('background-color','#0AFE47');
                $(this).addClass('AddApproved');
                $(this).removeClass('AddInactive');
                $(this).removeClass('AddDeleted');
            } else if (status == 'status_I') {
                $(this).closest('tr').css('background-color','#0AFE47');
                $(this).addClass('AddInactive');
                $(this).removeClass('AddApproved');
                $(this).removeClass('AddDeleted');
            }

        });
});

What I want to happen is when I fire $('#approve-all-button').click() and it detects a username that it applies the RED background to, for the script to also click the Delete "button" as well.

The code on the original site for the buttons looks like:

<div class="jquery-buttongroup ui-buttonset">
    <input type="radio" id="form-0-status_A" name="form-0-status" value="A" class="ui-helper-hidden-accessible">
    <label for="form-0-status_A" aria-pressed="false" class="ui-button ui-widget ui-state-default ui-button-text-only ui-corner-left" role="button" aria-disabled="false">
        <span class="ui-button-text">Approved</span>
    </label>
    <input type="radio" id="form-0-status_I" name="form-0-status" value="I" checked="checked" class="ui-helper-hidden-accessible">
    <label for="form-0-status_I" class="ui-state-active ui-button ui-widget ui-state-default ui-button-text-only" aria-pressed="true" role="button" aria-disabled="false">
        <span class="ui-button-text">Inactive</span>
    </label>
    <input type="radio" id="form-0-status_D" name="form-0-status" value="D" class="ui-helper-hidden-accessible">
    <label for="form-0-status_D" aria-pressed="false" class="ui-button ui-widget ui-state-default ui-button-text-only ui-corner-right" role="button" aria-disabled="false">
        <span class="ui-button-text">Deleted</span>
    </label>
</div>

There are 100 iteration of the above button code. Each iterations set of IDs has a variable that increase by 1 for each iteration eg.

id="form-0-status_D" 
id="form-1-status_D" 
id="form-2-status_D" 
id="form-3-status_D" 
id="form-4-status_D" 

As you can see I am using jQuery's each() to loop though each <tr> tag on the page, and using some form of $(this) to make any necessary changes.

How can I have the delete button selected automatically when the ID for the label and input is dynamic? And how do I actually get the Deleted button to be clicked?

Also to clear up any confusion I am simply adding the AddApproved/AddInactive/AddDeleted class for tallying purposes.

I have yet to implement the counter for this, but I already know how I am going to make that work.

P.S. This is my first time using jQuery, so this is as much as a tool for my place of employment as it is a learning experience. If some of the code seems nOOby I do apologize.

Edit +

I have gone though and 'refactored' as suggested. I actually noticed a slight speed increase in processing all the table rows.

Also per suggestion I've added some form of '$('#form-'+i+'-status_D').trigger('click');' to my script. However when I save and run the script the delete button is not triggered when it should be. The default action for the Approve All (which I hijacked and turned into Scan + Detect) is still applied. I tried adding i.preventDefault(); But the dafault action is still executed.

New Code:

$(document).ready(function() {
    // Rename Approve All Button
    $('#approve-all-button span').text('Scan + Detect');

    // The Magic
    $('#approve-all-button').click(function(i) {
        i.preventDefault();
        var Current_Name = '';
        // Loop through TR
        $('tr').each(function(i) {
            if (i > 0) {
                var _self = $(this)
                // Get Current Username in Loop
                Current_Name = _self.children('.username').text();
                // Apply Default Color to All (Green)
                _self.css('background-color', '#0AFE47');
                // Apply Approved Class to All
                _self.addClass('AddApproved');
                // Hide Creation Date / Last Login
                _self.children('.nowrap').css('opacity','.1').css('background-color','white');
                // Get Current Username Length
                var nlen = Current_Name.length;

                // If Name Length is <= 3 or >= 15 Apply Color (Red)
                if ((nlen <= 3) || (nlen >= 15)){
                    _self.css('background-color','#FF7575').
                        addClass('AddDeleted').
                        removeClass('AddApproved').
                        removeClass('AddInactive');
                    $(_self).children('#form-'+i+'-status_D').trigger('click');
                }


                var nDigits = 0;
                for ( var t=0; t<nlen; t++) {
                    var chr = Current_Name.charAt(t);
                    if (chr >= "0" && chr <= "9") nDigits++;
                }
                var charcount = nlen - nDigits;

                if ((nDigits >=6) || (charcount < 3) || (nDigits == nlen))  { 
                    _self.css('background-color','#FF7575').
                        addClass('AddDeleted').
                        removeClass('AddApproved').
                        removeClass('AddInactive');
                    $(_self).children('#form-'+i+'-status_D').trigger('click');
                }
            }
        });
    });
        // On Button Click, Change Background and Add/Remove class
        $('label').click(function(i) {
            var _self = $(this)
            var button = _self.attr('for');
            var status =  button.substring(button.lastIndexOf('-') + 1);
            if (status == 'status_D') {
                _self.closest('tr').css('background-color','#FF7575').
                    addClass('AddDeleted').
                    removeClass('AddApproved').
                    removeClass('AddInactive');
            } else if (status == 'status_A') {
                _self.closest('tr').css('background-color','#0AFE47').
                    addClass('AddApproved').
                    removeClass('AddInactive').
                    removeClass('AddDeleted');
            } else if (status == 'status_I') {
                _self.closest('tr').css('background-color','#0AFE47').
                    addClass('AddInactive').
                    removeClass('AddApproved').
                    removeClass('AddDeleted');
            }

        });
});

Edit ++

Since Technically I do not need the Approve All functionality (which is why I hijacked it with my own click(function(){}) I tried adding $('#approve-all-button span').unbind('click'); Unfortunately after saving and refreshing the page, the original approve all functionality is still there. Stuck +1

Edit +++

I found my mistake there, I was still including the span tag from the line I copied and pasted it over from. When I removed span from the code $('#approve-all-button').unbind('click'); the original event is no longer called. All I need to figure out is how to manually click the buttons, programmatically that is.


回答1:


Check out jQuery#trigger. It will let you raise events willy nilly. :)

In this case it would be something like:

$('#form-'+i+'-status_D').trigger('click');

Also, I would suggest some refactoring:

// If Name Length is <= 3 or >= 15 Apply Color (Red)
if (nlen <= 3 || nlen >= 15) {
  $(this).css('background-color','#FF7575').
    addClass('AddDeleted').
    removeClass('AddApproved').
    removeClass('AddInactive');
}

jQuery functions can generally be chained, so you don't need to (and shouldn't) repeatedly do $(this). At worst, you should do something like var self = $(this) and then use self instead of rerunning jQuery's wrapper on this over and over again.


Based on your comments, the effect you get from clicking the 'Click Me' span in the following example is what you're after?

<html>
  <head>
    <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
    <script type="text/javascript">
      $(function() {
        $('#click-me').click(function() {
          $('label[for=test]').trigger('click');
        });
      });
    </script>
  </head>
  <body>
    <span id="click-me">Click Me</span>
    <input type="radio" id="test">
    <label for="test">Deleted</label>
  </body>
</html>



回答2:


Trigger won't work as I explained on the other question you asked. The other answer seems to be correct as you focused on Trigger only.

Seems like you don't have any JS code associated with the radio buttons. In this case I would do:

$(_self).children('#form-'+i+'-status_D').prop("checked", true);

That's all you need.



来源:https://stackoverflow.com/questions/8102186/programmatically-click-on-label-radio-or-fire-event

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!