Javascript 增加 URL 中找到的第一个数字而不是图像 ID

Javascipt increases the 1st number found in URL instead of the image id

简而言之,下面的代码将增加 url 中的图像编号,以便导航到下一张图像:

https://bwrtsa.co.za/photos/test-gallery/#image1

https://bwrtsa.co.za/photos/test-gallery/#image2

问题是当我在 url 中有一个数字 'earlier on' 时,该数字会增加而不是图像编号:

https://bwrtsa.co.za/photos/test-gallery-1/#image1

https://bwrtsa.co.za/photos/test-gallery-2/#image1

更详细:

我有以下代码为我的图库自定义 post 类型创建灯箱。 为了让灯箱导航正常工作,我需要计算灯箱上的图像总数。一切正常,单击下一步时,#image1 变为#image2。 问题是每当 post 在 slug 中有一个数字时,就会增加该数字而不是图像编号。

以下链接将演示该问题(单击图片打开灯箱并导航至下一张图片)

post 标题中有一个数字: https://bwrtsa.co.za/photos/test-gallery-1/

没有post标题中的数字: https://bwrtsa.co.za/photos/test-gallery/

<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
    <div class="entry-content">
      <div class="photos-header">
        <?php the_title( '<h2 class="entry-title">', '</h2>' ); ?>
        <?php the_excerpt(); ?>
        <span class="photos-header-notice">
          Click on any image to enlarge and see the caption.
        </span>
      </div>
     
 
 <?php
$images = get_field('gallery_images');
$itotal = count($images);
$i = 0;

if( $images ): ?>

<div class="wrapper">
  <div class="grid-gallery">
    <?php foreach( $images as $image ): ?> 
    <?php $i++ ?>  

      <div class="box boxbg">
        <a href="#image<?php echo $i; ?>" class="ioverlay">
          <img src="<?php echo esc_url($image['sizes']['galleryThumb']); ?>" alt="Thumbnail of <?php echo esc_url($image['alt']); ?>" />
          <div class="text">
            <span>View</span>
          </div>
        </a>
      </div> <!-- BOX END -->

      <?php endforeach; ?> 
    </div> <!-- END GRID -->
    

<?php
$slug = $post->post_name; 
$images = get_field('gallery_images');
$itotal = count($images); 
$i = 0; 

foreach( $images as $image ): 
$i++;
?>


  <div class="lightbox short-animate" id="image<?php echo $i; ?>">
    <img src="<?php echo esc_url($image['sizes']['galleryLarge']); ?>" alt="Image <?php echo esc_url($image['alt']); ?>" class="long-animate" />
  </div>

<?php endforeach; ?> 

<?php
global $post;
?>


<div class="short-animate" id="close-wrapper">
  <!-- <a href="/#Gallery" id="close-lightbox" class="long-animate"></a> -->
    <a href="/<?php echo $slug ?>" id="close-lightbox" class="long-animate"></a>
</div>
    
<div class="short-animate" id="next-wrapper">
  <a href="#" id="next-lightbox" class="long-animate"></a>
</div>
    
<div class="short-animate" id="prev-wrapper">
  <a href="#" id="prev-lightbox" class="long-animate"></a>
</div>


  
</div>
<?php endif; ?>


</div> <!-- CONTAINER -->
</div> <!-- MODULE -->
<?php // endif; ?>

<script type="text/javascript">
'use strict';

let link;
let imageCount = <?php echo $itotal; ?>;
let regExDigit = /\d+/;

function imageLink() {
  let regExImage = /#image\d+/;
  let image = location.href;
  link = regExImage.exec(image)[0];
  link = regExDigit.exec(link)[0];
}

let next = document.getElementById('next-lightbox');
let prev = document.getElementById('prev-lightbox');

next.addEventListener('click', evt => {
  evt.preventDefault();
  imageLink();
  let newLink = Number(link) + 1;
  if (newLink > imageCount) newLink = 1;  
  location.href = location.href.replace(regExDigit, newLink);
});

prev.addEventListener('click', evt => {
  evt.preventDefault();
  imageLink();
  let newLink = Number(link) - 1;
  if (newLink < 1) newLink = imageCount;
  location.href = location.href.replace(regExDigit, newLink);
});
</script>







</div><!-- entry-content -->
</article> 
<!--</div> #post-## -->

谢谢

不是用 location.href = location.href.replace(regExDigit, newLink); 替换整个 URL 中的数字,而是只想替换 URL 的散列部分(即 [= 之后的部分) 16=])

我们可以做的是替换号码后生成新的URL,而不是替换当前URL中的号码。这确保我们 更改图像编号。您的新 imageLink 函数将如下所示(我还删除了全局变量以使代码更清晰):

/* 
Get the current image url, replace the number in the hash (#imageN) and return the new URL
Note the new parameter: changeBy = what to change the image number by: 1 for next, -1 for prev
*/
function imageLink(changeBy) {
  let regExDigit = /\d+/;
  var currentNum = 0;

  let currentURL = location.href;  

  var parts = currentURL.split("#");   // split URL to get main url and image hash
  var url_gallery_part = parts[0];    // e.g. http://www.example.com/photos/test-gallery-1/
  var imagehash = parts[parts.length - 1];  // e.g. image1

  // if there is a hash in the url, extract the number
  if (imagehash) currentNum = regExDigit.exec(imagehash)[0];

  // Call our function that calculates the prev/next number
  // pass in the current image number and change to change by (e.g. +1 or -1)
  newNum = getNewNum(currentNum, changeBy);

  // rebuild our full image url replacing the number with the enw number
  newImageLink = url_gallery_part + "#" + imagehash.replace(regExDigit, newNum);

  return newImageLink;
}

这是做什么的:

  1. 我们添加了一个新参数 changeBy 来告诉函数更改图像的内容,例如+1 为下一个,-1 为上一个
  2. split URL 基于 # 的部分 - 这将为我们提供主要的 url 以及图像的哈希值。
  3. 使用正则表达式从图像哈希中提取数字
  4. 根据我们想要下一张 (+1) 还是上一张 (-1) 图像计算新数字
  5. 重建我们的完整图像 URL 并 return 它到我们的处理程序

我们还可以整理代码来计算新的图像编号 - 我们传入当前图像编号和我们的 changeBy 参数,它 return 是新编号:

/* 
currentNum: the current image number
changeBy: what to change the number by, e.g. 1 for next, -1 for previous 
*/
function getNewNum(currentNum, changeBy) {
  newNum = Number(currentNum) + changeBy;  // adjust the current number
  
  // Make sure it is within the bounds of the number of images
  if (newNum > imageCount)  newNum = 1;
  else if (newNum < 1)      newNum = imageCount;

  return newNum;
}

这里唯一要注意的是,它在您的事件处理程序中组合了 2 个独立的代码块。通过传入 1 或 -1,该值将从当前数字中添加或减去,因此它适用于下一个 上一个。

现在我们的偶数处理程序是这样的:

next.addEventListener('click', evt => {
  evt.preventDefault();
  // get the full URL for next image by adding 1 to the current image
  location.href = getImage(1);   
});

prev.addEventListener('click', evt => {
  evt.preventDefault();
  // get the full URL for prev image by subtracting 1 from the current image
  location.href = imageLink(-1);
});

工作示例: 您可以在下面看到这段代码,通过一些小的调整以使用显示的 url 字符串而不是页面 [=62] =](这显然不会在这里工作):

let imageCount = 5;

// Display elements for demo only
let next = document.getElementById('next-lightbox');
let prev = document.getElementById('prev-lightbox');
let imageDisplay = document.getElementById('imageDisplay');

/* 
Get the current image url, replace the number in the hash (#imageN) and return the new 
URL
Note the new parameter: changeBy = what to change the image number by: 1 for next, -1 for prev
*/
function imageLink(changeBy) {
  let regExDigit = /\d+/;
  var currentNum = 0;

  var currentURL = imageDisplay.innerHTML;  // for demo only - use location.href
  //let currentURL = location.href;  

  // split URL to get main url and image hash
  var parts = currentURL.split("#");
  var url_gallery_part = parts[0];
  var imagehash = parts[parts.length - 1];

  // if there is a hash in the url, extract the number
  if (imagehash) currentNum = regExDigit.exec(imagehash)[0];

  // Call our function that calculates the prev/next number
  // pass in the current image number and chage t ochange by (e.g. +1 or -1)
  newNum = getNewNum(currentNum, changeBy);

  // rebuild our full image url replacing the number with the enw number
  newImageLink = url_gallery_part + "#" + imagehash.replace(regExDigit, newNum);

  return newImageLink;
}

/* 
currentNum: the current image number
changeBy: what to change the number by, e.g. 1 for next, -1 for previous 
*/
function getNewNum(currentNum, changeBy) {
  newNum = Number(currentNum) + changeBy; // adjust the current number
  
  // Make sure it is within the bounds of the number of images
  if (newNum > imageCount)  newNum = 1;
  else if (newNum < 1)      newNum = imageCount;
  return newNum;
}

next.addEventListener('click', evt => {
  evt.preventDefault();
  // get the full URL for next image by adding 1 to the current image
  imageDisplay.innerHTML = imageLink(1);  // for demo. replace with below
  //  location.href = imageLink(1);
});

prev.addEventListener('click', evt => {
  evt.preventDefault();
  // get the full URL for prev image by subtracting 1 from the current image
  imageDisplay.innerHTML = imageLink(-1); // for demo. replace with below
  //  location.href = imageLink(-1);
});
<button id="next-lightbox">Next</button>
<button id="prev-lightbox">Prev</button>
<div id="imageDisplay">https://www.example.com/photos/test-gallery-1/#image1</div>