2

Just trying to get these videos to play on mouse over. I can see from the console I need to make a function instead of using a string (other SO answers use strings), so how can I do this without creating too much extra code? Ideally I want the functions set right on the onMouseOver & onMouseOut attributes.

        <video 
          poster="https://i.imgur.com/Us5ckqm.jpg"
          onMouseOver="this.play()" 
          onMouseOut="this.pause();this.currentTime=0;"
          src={`${vid.videos.tiny.url}#t=1`}
        </video>

Have also tried

        <video 
          poster="https://i.imgur.com/Us5ckqm.jpg"
          onMouseOver={() => this.play()}
          onMouseOut={() => this.pause()}
          src={`${vid.videos.tiny.url}#t=1`} >
        </video>

Which gives me the error: Cannot read property 'play' of undefined.

Edit Not sure this is relevant, but this code above resides inside of a map function, which is also part of a get request. Here is the full function:

  const fetchVideos = async (amount, category) => {
    const response = await axios.get('https://pixabay.com/api/videos/', {
      params: {
        key: '123456123456123456',
        per_page: amount,
        category: category
      }
    })
    console.log(response)
    const vidsAsHtml = response.data.hits.map(vid => {
      return (
        <div className={`${props.page}--grid-content-wrapper`} key={vid.picture_id}>
          <div className={`${props.page}--grid-video`}>
            <video className=".video"
              poster="https://i.imgur.com/Us5ckqm.jpg"
              onMouseOver={() => this.play()}
              onMouseOut={() => this.pause()}
              src={`${vid.videos.tiny.url}#t=1`} >
            </video>
          </div>
          <div className={`${props.page}--grid-avatar-placeholder`}></div>
          <div className={`${props.page}--grid-title`}>{vid.tags}</div>
          <div className={`${props.page}--grid-author`}>{vid.user}</div>
          <div className={`${props.page}--grid-views`}>{abbreviateNumbersOver999(vid.views)} 
            <span className={`${props.page}--grid-date`}> • 6 days ago</span>
          </div>
        </div>
      )
  })
  setResource(vidsAsHtml)
}

Edit 2: Seems like some other people had problem with the 'this' keyword inside of mapping statement. Although I tried these solutions and 'this' is still undefined.

Robert C
  • 756
  • 10
  • 25
  • Is this your actual code? Cause if it is, you should pass a function to onMouseOver and onMouseOut. `onMouseOver={() => this.play()}` `onMouseOut={() => this.pause(); this.currentTime=0}` – dev Dec 06 '19 at 05:21
  • Already tried that way -- gives me the console error Cannot read property 'play' of undefined – Robert C Dec 06 '19 at 05:23
  • Closed it as duplicate of your other question (since it's about the same problem). – Felix Kling Dec 06 '19 at 09:31

2 Answers2

10

A user named Felix Kling gave a very simple answer that solved my problem in this post:

Event handler props are expected to be passed a function. Currently you are trying to pass the return values of this.play() and this.pause() as event handlers, which wouldn't work anyway.

Also React doesn't make the element available to the event handler via this, but you can access it via event.target:

<video
  poster="https://i.imgur.com/Us5ckqm.jpg"
  onMouseOver={event => event.target.play()}
  onMouseOut={event => event.target.pause()}
  src={`${vid.videos.tiny.url}#t=1`} >
</video>

Find the working solution here.

Abhinav Kinagi
  • 3,653
  • 2
  • 27
  • 43
Robert C
  • 756
  • 10
  • 25
-3

Some quick googleing and i found this

var figure = $(".video").hover( hoverVideo, hideVideo );
function hoverVideo(element) { 
$('video', this).get(0).play(); 
}
function hideVideo(e) {
$('video', this).get(0).pause(); 
}

this is however jquery so you must include the library in your html.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
ari b
  • 1
  • 1