简体   繁体   English

重新加载验证码图像

[英]Reload captcha image

I have a php script which generates a png image with a captcha code as image text. 我有一个PHP脚本生成一个png图像,其中验证码为图像文本。

session_start();   
$captchanumber = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz'; 
$captchanumber = substr(str_shuffle($captchanumber), 0, 8); 
$_SESSION["code"] = $captchanumber; 
$image = imagecreatefromjpeg("cap.jpg");     
$black  = imagecolorallocate($image, 160, 160, 160);   
$font = '../assets/fonts/OpenSans-Regular.ttf';  
imagettftext($image, 20, 0, 35, 27, $black, $font, $captchanumber);   
header('Content-type: image/png');    
imagepng($image);
imagedestroy($image);

I want to reload the image via jQuery or JavaScript,so i'm using something like this: 我想通过jQuery或JavaScript重新加载图像,所以我使用这样的东西:

$(document).ready(function(e) {
    $('.captcha').click(function(){
        alert('yolo');
        var id = Math.random();
        $(".captcha").replaceWith('<img class="captcha" src="img/captcha.php?id='+id+'" />');
        id ='';

    });
});

the field: 场:

<img class="captcha" src="img/captcha.php">

As the first attempt,it works , but after that if i click on the field again it won't work anymore and i have no idea why . 作为第一次尝试,它有效,但在那之后,如果我再次点击该字段,它将不再工作,我不知道为什么。

You are replacing the dom element with new element, it will destroy all attached event handlers. 您正在用新元素替换dom元素,它将销毁所有附加的事件处理程序。

Method 1: You can resolve this by using event delegation to listen dynamically added elements event. 方法1:您可以通过使用事件委派来侦听动态添加的元素事件来解决此问题。

$(document).ready(function(e) {
    $('body').on('click', '.captcha', function(){
        alert('yolo');
        var id = Math.random();
        $(this).replaceWith('<img class="captcha" src="img/captcha.php?id='+id+'" />');
    });
});

 $(document).ready(function(e) { $('body').on('click', '.captcha', function() { alert('yolo'); var id = Math.random(); $(this).replaceWith('<img class="captcha" src="img/captcha.php?id=' + id + '" />'); }); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <img class="captcha" src="img/captcha.php"> 


Method 2: Instead of replacing entire element just update the img src attribute with new url. 方法2:只需用新url更新img src属性,而不是替换整个元素。

$(document).ready(function(e) {
    $('.captcha').click(function(){
        alert('yolo');
        var id = Math.random();
        $(this).attr('src', 'img/captcha.php?id='+id);
    });
});

 $(document).ready(function(e) { $('.captcha').click(function() { alert('yolo'); var id = Math.random(); $(this).attr('src', 'img/captcha.php?id=' + id); }); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <img class="captcha" src="img/captcha.php"> 


Method 3: Also you can get it done with pure JavaScript with same logic as previous. 方法3:您也可以使用与之前相同逻辑的纯JavaScript完成它。

 document.querySelector('.captcha').addEventListener('click', function() { alert('yolo'); var id = Math.random(); this.setAttribute('src', 'img/captcha.php?id=' + id); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <img class="captcha" src="img/captcha.php"> 


Method 4: Setting onClick attribute to the element and handling the click event with pure JavaScript, where you need to pass this as argument to refer the element. 方法4:onClick属性设置为元素并使用纯JavaScript处理click事件,您需要将this作为参数传递以引用元素。

 function captcha(ele) { alert('yolo'); var id = Math.random(); ele.setAttribute('src', 'img/captcha.php?id=' + id); } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <img class="captcha" onclick="captcha(this)" src="img/captcha.php"> 

The reason your code only works once is because the original element with captcha class is replaced and the click is no longer detected . 您的代码仅工作一次的原因是因为替换了具有验证码类的原始元素并且不再检测到单击

Solution

A clean solution would be to replace the src of the image instead of the complete element. 一个干净的解决方案是替换图像的src而不是完整的元素。

Working example 工作实例

Jquery jQuery的

  $(document).ready(function () {
        $("#changeThis").click(
            function () {
                changeImage();
            }            
        );
    });

function changeImage() {
   //we want whole numbers not numbers with dots here for cleaner urls
   var id = Math.floor((Math.random() * 1000) + 1);
   $('#changeThis').attr("src",'img/captcha.php?id='+id);
   //Not sure why you want to empty id though.
   id ='';
}

Or in oneline: 或者在线:

$("#changeThis").click($('#changeThis').attr("src",'img/captcha.php?id='+Math.floor((Math.random() * 1000) + 1)));

HTML For unique elements use the id="" syntax instead of class="", class is used when multiple elements can have the same class, id is an identifier for a unique element. HTML对于唯一元素,使用id =“”语法而不是class =“”,当多个元素可以具有相同的类时使用class,id是唯一元素的标识符。

<img class="captcha" id="changeThis" src="img/captcha.php">

Might just be a problem with binding events to elements that your code replaces. 可能只是将事件绑定到代码替换的元素的问题。 Consider delegate binding to the document instead: 考虑委托绑定到文档:

// Replace
$(document).ready(function(e) {
    $('.captcha').click(function(){
// With
$(document).ready(function(e) {
    $('.captcha').on('click', document, function(){

Okay. 好的。 The problem is that you declare the id variable, and you try to redeclare it in the second function call, when there already is an id variable, so it will silently be ignored and the empty string used instead. 问题是你声明了id变量,当你已经有一个id变量时,你尝试在第二个函数调用中重新声明它,所以它将被静默忽略,而是使用空字符串。

Try moving var id =''; 尝试移动var id =''; out of the function, and use id = Math.random() in the function. 退出函数,并在函数中使用id = Math.random()

This is a delegation issue, as you have inserted a new element, so the event listener is removed, there are many solutions: 这是一个委托问题,因为您已插入新元素,因此删除了事件侦听器,有许多解决方案:

Solution 1: 解决方案1:

Use inline event binding 使用内联事件绑定

function rebindCaptcha()
{
var id = Math.random();
        $(".captcha").replaceWith('<img onclick="rebindCaptcha()" class="captcha" src="img/captcha.php?id='+id+'" />');
}

Solution 2: 解决方案2:

Keep your element in dom, and just change the src attribute: 将您的元素保存在dom中,只需更改src属性:

$(document).ready(function(e) {
      $('.captcha').click(function(){
          var id = Math.random();
          this.src = 'img/captcha.php?id='+id+';
          id ='';

      });
  });  

Just for your reference, jQuery delegation can be done with like: 仅供您参考,jQuery委托可以完成如下:

$(".parent .child").on("event",function(){/*your handler here*/}) 

or 要么

$(".parent").on("event",".child",function(){/*your handler here*/})

Usually pick a parent that you are sure it will always exist in your dom, and always attach listener after document ready event. 通常选择一个您确定它将始终存在于您的dom中的父级,并始终在文档就绪事件之后附加侦听器。

For me its working as i say you have to use id in javascript for changing things 对我来说,它的工作,因为我说你必须在javascript中使用id来改变事物

// reload is your button reload and captcha must be a div who surrounding the captcha img

document.querySelector('#reload').addEventListener('click', function(e){
  var reload = document.getElementById('captcha')
  reload.innerHTML = "your new logic"
})

//reload.innerHTML gonna be the new captcha html code //reload.innerHTML将成为新的验证码html代码

In order to load the image with new code, you can use version paramter for captcha.php. 为了使用新代码加载图像,您可以使用版本参数for captcha.php。 See the following code. 请参阅以下代码。

<img class="captcha" id="secure_code" src="img/captcha.php"> <a href="#" id="reload_captcha">Reload</a> 

$(document).ready(function(e) {
    $('#relaod_captcha').click(function(e) {
        e.preventDefault() ;
        $('#secure_code').attr('src', "img/captcha.php?ver="+Math.random()) ;
    }) ;
}) ;

I wish it will help. 我希望它会有所帮助。

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

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