简体   繁体   中英

Cancelling a javascript function that fires from onClick in a link

My page has a form with 20 select attributes , which, for the sense of the form are grouped in 10 related pairs.

I gave users the ability to randomise the options for each of the 10 pairs by a jQuery-dependent javascript.

The randomisation of the selects works fine. Clicking on one of the "Randomise" links will randomise the pair in question, while the other selection-pairs remain as they are.

The problem is in the onClick alert/check on the link: because the links are always "listening" for the click, even if the user clicks "Cancel", the randomisation of the selects still takes place.

What I'm looking for is a way to be able to place an alert on the link that will give the user the ability to stop the randomisation function from firing if the choice is "Cancel" or similar.

My javascript coding skills are not that great, but I'm guessing that the inline link code may not be able to be modified for this, because the links are always "listening" for any sort of click, and that the javascript function itself would have to be altered to enable the placing of an alert in the link which can cancel the randomisation or allow it to proceed.

 jQuery(document).ready(function() { jQuery("#randomSelect1").click(function() { var select = document.getElementById('pair_1_phrase'); var items = select.getElementsByTagName('option'); var index = Math.floor(Math.random() * items.length); select.selectedIndex = index; var select = document.getElementById('pair_1_descriptor'); var items = select.getElementsByTagName('option'); var index = Math.floor(Math.random() * items.length); select.selectedIndex = index; }); jQuery("#randomSelect2").click(function() { var select = document.getElementById('pair_2_phrase'); var items = select.getElementsByTagName('option'); var index = Math.floor(Math.random() * items.length); select.selectedIndex = index; var select = document.getElementById('pair_2_descriptor'); var items = select.getElementsByTagName('option'); var index = Math.floor(Math.random() * items.length); select.selectedIndex = index; }); //8 more pairs like this.. });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <select name="pair_1_phrase" id="pair_1_phrase"> <option value="0">State</option> <option value="1">Condition</option> <option value="2">Health</option> <option value="3">Strength</option> </select> <select name="pair_1_descriptor" id="pair_1_descriptor"> <option value="0">moderate</option> <option value="1">great</option> <option value="2">good</option> <option value="3">superior</option> </select> <p><a onClick="return confirm('Randomise these selects?');" id="randomSelect1" href="#">Randomise</a></p> <select name="pair_2_phrase" id="pair_2_phrase"> <option value="0">Requirement</option> <option value="1">Need</option> <option value="2">Lack</option> <option value="3">Necessity</option> </select> <select name="pair_2_descriptor" id="pair_2_descriptor"> <option value="0">urgent</option> <option value="1">pressing</option> <option value="2">extreme</option> <option value="3">crucial</option> </select> <p><a onClick="return confirm('Randomise these selects?');" id="randomSelect2" href="#">Randomise</a></p> <!-- 8 more pairs like this.. -->

If I got you correctly, you should move the confirm to click event block, see below:

jQuery("#randomSelect1").click(function () {
    if(confirm('Randomise these selects?')) {
        var select = document.getElementById('pair_1_phrase');
        var items = select.getElementsByTagName('option');
        var index = Math.floor(Math.random() * items.length);
        select.selectedIndex = index;

        var select = document.getElementById('pair_1_descriptor');
        var items = select.getElementsByTagName('option');
        var index = Math.floor(Math.random() * items.length);
        select.selectedIndex = index;
    }
    // else ...
});

And of course remove the inline confirm

<p><a id="randomSelect1" href="#">Randomise</a></p>

Following is not related to your question, but you could make your life easier by refactoring you code, something like this:

var randomizeSelect = function($select) {
  var $items = $select.find('option'),
      index = Math.floor(Math.random() * $items.length);

    $select[0].selectedIndex = index;
}

var randomize = function(id) {
  if(confirm('Randomise these selects?')) {
    randomizeSelect($('#pair_' + id + '_phrase'));   
    randomizeSelect($('#pair_' + id + '_descriptor'));    
  }
}

jQuery("#randomSelect1").click(function() {
  randomize(1);
});

jQuery("#randomSelect2").click(function() {
  randomize(2);
});

You can do more, for example add a data-id , then bind the click event once on [data-id] , as I did in this pen

Here is a simpler version

  1. Wrap each set in a container, here a div
  2. Navigate relatively to this container
  3. Cancel the link click

The script here will work on any number of sets of phrase/desc class set on the select

 $(function() { $(".rdn").on("click", function(e) { e.preventDefault(); // stop click const $parent = $(this).closest("div"); const $phrase = $parent.find(".phrase"); const $desc = $parent.find(".descriptor"); const setText = "Randomise set #"+$phrase.attr("name").split("_")[1]+"?"; if (!confirm(setText)) return; let len; let index; len = $('option',$phrase).length; index = Math.floor(Math.random() * len); $phrase[0].selectedIndex = index; len = $('option',$desc).length; index = Math.floor(Math.random() * len); $desc[0].selectedIndex = index; }); });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div> <select name="pair_1_phrase" class="phrase"> <option value="0">State</option> <option value="1">Condition</option> <option value="2">Health</option> <option value="3">Strength</option> </select> <select name="pair_1_descriptor" class="descriptor"> <option value="0">moderate</option> <option value="1">great</option> <option value="2">good</option> <option value="3">superior</option> </select> <p><a class="rdn" href="#">Randomise</a></p> </div> <div> <select name="pair_2_phrase" class="phrase"> <option value="0">Requirement</option> <option value="1">Need</option> <option value="2">Lack</option> <option value="3">Necessity</option> </select> <select name="pair_2_descriptor" class="descriptor"> <option value="0">urgent</option> <option value="1">pressing</option> <option value="2">extreme</option> <option value="3">crucial</option> </select> <p><a class="rdn" href="#">Randomise</a></p> </div>

Generally randomizing should happen in result of confirmation, so you should or have a listener and do confirm inside it, or do check in <a onClick="confirm... :

 // a bit optimized way, instead of copy/pasting same code with a different id. function selectRandomValue(elSelect) { var items = elSelect.getElementsByTagName('option'); var index = Math.floor(Math.random() * items.length); elSelect.selectedIndex = index; } // also a bit optimized function randomizeValuesInBlock(index) { var select = document.getElementById(`pair_${index}_phrase`); selectRandomValue(select); var select = document.getElementById(`pair_${index}_descriptor`); selectRandomValue(select); }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <select name="pair_1_phrase" id="pair_1_phrase"> <option value="0">State</option> <option value="1">Condition</option> <option value="2">Health</option> <option value="3">Strength</option> </select> <select name="pair_1_descriptor" id="pair_1_descriptor"> <option value="0">moderate</option> <option value="1">great</option> <option value="2">good</option> <option value="3">superior</option> </select> <p><a onClick="confirm('Randomise these selects?') ? randomizeValuesInBlock(1) : '';" id="randomSelect1" href="#">Randomise</a></p> <select name="pair_2_phrase" id="pair_2_phrase"> <option value="0">Requirement</option> <option value="1">Need</option> <option value="2">Lack</option> <option value="3">Necessity</option> </select> <select name="pair_2_descriptor" id="pair_2_descriptor"> <option value="0">urgent</option> <option value="1">pressing</option> <option value="2">extreme</option> <option value="3">crucial</option> </select> <p><a onClick="confirm('Randomise these selects?') ? randomizeValuesInBlock(2) : '';" id="randomSelect2" href="#">Randomise</a></p>

After answer:

8 more pairs like this..

Usually this means that there is an area for optimization, for example you can put values in some array, than using javascript loop through it and dynamically add every select in a DOM.

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