javascriptdom-eventsmouseovermouseout

mouseover and mouseout events not firing using pure js


I have a setup where i am trying to assign a mouseover and mouseout event on a div, but they dont appear to be firing. Right now i just have it trying to console.logthe mouseout event and add classes to the body as well for the mouseover event.

I have trying using .addEventListener('mouseover', function(){}) instead of .onmouseover to no avail. I have also tried mouseenter and mouseleave but these are IE only events.

I need to use pure Javascript rather than any 3rd party library, this also needs to work in IE8+.

HTML

<div class="of_expandable" data-channel="2935725596001" data-muted="1" data-skin="dark"></div>

JS

/*
    for each expandable element this function:
    - parses the data attributes for handing to the embeds
    - styles the expandable div
    - binds the hover event to the div
*/
function processExpandable (elm, index){
    elm.className += " processed";
    elm.id = exp_ns + "_expandable_" + index;

    // option parsing
    var options = {};
    options.skin = elm.getAttribute("data-skin");
    if(!options.skin){
        options.skin = 'light';
    }

    // styling
    elm.style.width = "300px";
    elm.style.height = "250px";
    elm.style.position = "relative";
    elm.style.backgroundColor = "#000";

    // add events to elm
    elm.onmouseover = function (){
        launchModal(elm, options.skin);
    };
    elm.onmouseout = function (){
        console.log('mouseout');
    };
}

/*
    opens the modal and populates
*/
function launchModal (elm, skin){
    console.log('entered');
    document.body.className += " " + exp_ns + "_modal_open modal_skin_" + skin;
}

/*
    closes the modal and clears
*/
function closeModal (){
    // TODO: clear data from modal
    var pattern = "/\b" + exp_ns + "_modal_open\b/";
    document.body.className = document.body.className.replace(pattern,'');
    var pattern = "/\bmodal_skin_light\b/";
    document.body.className = document.body.className.replace(pattern,'');
    var pattern = "/\bmodal_skin_dark\b/";
    document.body.className = document.body.className.replace(pattern,'');
}


/*
    adds the modal element waiting to be triggered by the expandables
    - adds background
    - adds modal box
*/
function addModal (){
    var modalHTML = '<div id="' + exp_ns + '_modal" class="exp_modal"></div><div id="' + exp_ns + '_modal_back" class="exp_modal_back"></div>';
    document.body.innerHTML += modalHTML;
}


/*
    tests if an element has a class
*/
function hasClass(elm, cls) {
    return (' ' + elm.className + ' ').indexOf(' ' + cls + ' ') > -1;
}
var exp_ns = "of"
  , expandables = getElementsByClassName(exp_ns + '_expandable')
  , hoverTimer
  , hoverPause = 1000;

if(expandables.length > 0){
    for (var i = 0; i < expandables.length; i++){
        if(!hasClass(expandables[i], "processed")){
            // make sure we arent adding twice from a double include
            processExpandable(expandables[i], i);   
        }
    }
    // make sure we arent adding twice from a double include
    var modal = document.getElementById(exp_ns + '_overlay');
    if(!modal){
        addModal();
    }
}else{
    console.log('warning: no expandable elements found');
}

here's a JSFiddle

SOLUTION UPDATE:

So it appears that the reason this was breaking was because of the way that I was inserting the modal elements using document.body.innerHTML += . Which I think must read all the innerHTML with the newly appended content. As a better solution I used this:

function addModal (){
    var modalBack = document.createElement("div");
        modalBack.setAttribute("class", "exp_modal_back");
    document.getElementsByTagName("body")[0].appendChild(modalBack);
    var modalCont = document.createElement("div");
        modalCont.setAttribute("class", "exp_modal");
    document.getElementsByTagName("body")[0].appendChild(modalCont);
}

updated JSFiddle


Solution

  • Your problem is not with how you are using the event handlers. The problem is being caused by the "addModal" function called after the "processExpandable" function. I don't understand what you are trying to accomplish so I can't help you there, but it is a start.

    Also, I think you have a problem in the "launchModal" function. Do you really want to keep adding and adding values to the class attribute of the body?