Thắc mắc về JS và querySelector()

Cho em hỏi một chút ạ. Em đang có ý định khi click vào một ảnh bất kỳ thì ảnh được click sẽ trở thành ảnh trong javascript thông qua querySelector nhưng khi em code thì khi ấn vào một ảnh thì ảnh còn lại cũng biến thành ảnh trong js. Vậy cho em hỏi là có cách nào để khi em ấn vào một ảnh bất kì thì ảnh kia ko bị biến đổi, trừ khi em ấn vào nó thì nó mới biến đổi được không ạ.

Em xin cảm ơn ạ.

Đây là code HTML

 <!DOCTYPE html>
<html>
<link rel="stylesheet" type="text/css" href="style.css">
<head>
    <style>
    </style>
     <script src='script.js'defer></script>
</head>
<body>
      <h1>Click for a present:</h1>
      <img src=https://timviec365.com/pictures/images/coder-la-gi-3.jpg>
      <h1>Hello World</h1>
      <img src="https://img.timviec.com.vn/2020/10/coder-la-gi-2.jpg">
  </body>

Đây là code JavaScript:

function openPresent(event){
  const im = document.querySelectorAll('img');  
   let i=0;
   for(i=0;i<im.length;i++){
    im[i].src ='https://i2.wp.com/gsviec.com/wp-content/uploads/2020/02/coder-dev-1.jpeg?fit=900%2C500&ssl=1';
    im[i].removeEventListener('click',openPresent);
  }
}

  const image = document.querySelectorAll('img');
  let i;
  for(i=0;i<image.length;i++){
    image[i].addEventListener('click',openPresent);
  }

Sẽ tác dụng với tất cả hình ảnh có trên trang, vì nó căn cứ vào thẻ img. Nếu bạn chỉ muốn tác dụng vào hình ảnh nào đó không thôi, bạn phải đặt id hoặc class cho ảnh đó để chỉ chọn riêng nó chứ không “cào bừa” như hiện tại.

          <img class="click-here" src=https://timviec365.com/pictures/images/coder-la-gi-3.jpg>
          const im = document.querySelectorAll(".click-here");

Hy vọng giải quyết được vấn đề.

3 Likes

Bạn chỉ cần lấy event.target là đủ.

function openPresent(event){
  event.target.src ='https://i2.wp.com/gsviec.com/wp-content/uploads/2020/02/coder-dev-1.jpeg?fit=900%2C500&ssl=1';
}

event.target cho biết element nào đang trigger event đó,
ngoài ra còn event.currentTarget

4 Likes

có thể là bạn sẽ giải quyết được theo lời gợi ý của các bác ở trên
tuy nhiên bạn nên hiểu rõ code của mình, code chỉ là phụ, quan trọng là bạn cần biết mình làm gì
như case này là click thẻ img nào thì đổi src của thẻ img đó, từ đó lên giải pháp
bắt sự kiện click -> đổi src của thẻ img được click
như vậy bạn nhìn lại và giải thích lại dòng code của bạn xem, bạn đã thực hiện những bước trên có đúng hay chưa
hoăc ít ra nếu bạn đã nhìn thấy tất cả thẻ đều đổi src thì cũng nên thử đoán và kiểm dòng code đổi src, và việc đổi src của 1 thẻ (được click) lại cần phải dùng vòng lặp for thì có vô lý hay không, hay việc lý do gì bạn lại dùng vòng lặp for hay việc query selector all của bạn trả về cái gì …
việc này sẽ nâng cao khả năng code và tu duy của bạn hơn thay vì chỉ đơn thuần là giải quyết được một bài tập nho nhỏ

6 Likes

Cảm ơn lời khuyên của bạn

mình hoàn toàn đồng ý với điều này
nhưng phải nói function của js rất là hack não

  1. trong function của event bạn có thể dùng event.target.src hoặc this.src.
  2. Bạn cũng có thể dùng console để log object event đó ra
  3. hoặc dùng debugger để theo dõi các thuộc tính của nó.
  4. Bạn cũng có thể đổi thành arrow function và thử lại bước số 1, xem sự khác nhau.
4 Likes

rất đúng, việc học tập không chỉ dừng lại ở mức xong bài tập, mà còn phải mở rộng hơn hoặc sáng tạo hơn bằng việc chỉnh sửa lại bài làm để ra được cái gì đó mà có thể coi như là kiến thức mới hoặc để so sánh nhiều giải pháp khác nhau

3 Likes

cảm ơn bạn rất nhiều. Mình muốn hỏi là nếu mình muốn khi click vào một ảnh bất kì thì nó sẽ chuyển sang ảnh trong js, nhưng nếu mình click sang ảnh khác thì ảnh đấy sẽ biến thành js, đồng thời ảnh mà mình đã click lúc trước sẽ trở lại ảnh lúc chưa click thì mình làm thế nào ạ. Bạn có thể cho mình gợi ý được không, vì mình đã thử nhiều cách nhưng nó đều không làm được như thế

Cảm ơn lời khuyên từ các bạn

Có vô số cách bạn à. Mình gợi ý 2 cách mình thường dùng và ví dụ để bạn tham khảo

  1. Cách OOP
const image = document.querySelectorAll('img');
var imageCollection = [];
for(image in images) {
    imageCollection.push ( {
        img: image,
        oldsrc: image.src,
        newsrc: ''
   };
};
 
function openPresent(event) {
  var image = imageCollection.find(image => image.img == event.target); // check lại cách so sánh
  image.oldsrc = event.target.src;
  event.target.src ='https://i2.wp.com/gsviec.com/wp-content/uploads/2020/02/coder-dev-1.jpeg?fit=900%2C500&ssl=1';
  image.newsrc = event.target.src;
  imageCollection.forEach( image => {
      if(image.img != event.target) {
         image.img.src = image.oldsrc;
      }
  })
}
  1. Cách dùng DOM attribute
function openPresent(event) {
   const updatedImages = document.querySelectorAll('[data-old-src]');
   for (let i = 0; i < updatedImages.length; i++) {
     const img = updatedImages[i];
     img.src = img.dataset.oldSrc;
     img.removeAttribute('data-old-src');
   }
   const oldSrc = event.target.src;
   event.target.src ='https://i2.wp.com/gsviec.com/wp-content/uploads/2020/02/coder-dev-1.jpeg?fit=900%2C500&ssl=1';
   event.target.dataset.oldSrc = oldSrc;
}

Đây chỉ là 2 gợi ý theo 2 cách mình thường sử dụng. Đôi khi là kết hợp cả 2.
Với cách 1, thích hợp để quản lý khi tương tác các DOM elements khác nhau (vd img, button, input) hoặc shadow DOM
Với cách 2, tận dùng các custom attribute để lưu các thông tin cần thiết. Thiết lập các event theo selector tương ứng với các attribute đó. Cách này boostrap, các cổng thanh toán, google catpcha, … đang dùng.

2 cách này chỉ phù hợp khi bạn dùng javascript hoặc jquery. Nếu bạn dùng các framework như angular, reactjs, vuejs thì nên tận dụng các tính năng framework.

2 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?