1. In combat, when we put cursor on the CompactRaidFrame, we can see the tooltip which I just want see it out of combat. I checked the Blizzard code and in "FrameXML/CompactUnitFrame.xml", I found:

        <Scripts>
            <OnLoad function="CompactUnitFrame_OnLoad"/>
            <OnEnter function="UnitFrame_OnEnter"/>
            <OnLeave function="UnitFrame_OnLeave"/>
            <!--
            <OnEvent function="PlayerFrame_OnEvent"/>
            <OnUpdate function="PlayerFrame_OnUpdate"/>
            <OnReceiveDrag function="PlayerFrame_OnReceiveDrag"/>
            -->
        </Scripts>
    

    Then I tried to write an addon to customize the event OnEnter:

     local CompactUnitFrame_OriginalOnEnter = CompactUnitFrameTemplate:GetScript("OnEnter");
    
     local function CompactUnitFram_NewOnEnter(self)
         if not (InCombatLockdown()) then
            return CompactUnitFrame_OriginalOnEnter()
        end
     end
    
     local function OnEvent(self, event, AddOn)
         if AddOn == "Blizzard_CompactRaidFrames" then
             CompactUnitFrameTemplate:SetScript("OnEnter", CompactUnitFram_NewOnEnter)
            print("setscript successfully!");
        end
     end
    
     if (IsAddOnLoaded"Blizzard_CompactRaidFrames") then
         OnEvent(BlizzRaidFrames, "ADDON_LOADED", "Blizzard_CompactRaidFrames")
     else
         BlizzRaidFrames:RegisterEvent("ADDON_LOADED")
        BlizzRaidFrames:SetScript("OnEvent", OnEvent)
     end
    

    but when I ran this in game, I was told that CompactUnitFrameTemplate was nil.

    Then how can I hide the tooltip when I am in combat? Thanks very much!

    CompactUnitFrameTemplate is and always will be nil, it's a virtual frame. You must use a frame that is actually created from this template.

    But doing any of this will almost certainly taint the compact unit frames, which is not what you want. Your best bet is to instead use HookScript(), which wont' taint the frame.

    Thank you for your reply, I found the following code can help resolve this, let me share it:

     -- Get a pointer to the original function:
     local original_UnitFrame_OnEnter = UnitFrame_OnEnter
     -- Overwrite the original function with a new one:
     UnitFrame_OnEnter = function(frame)
         -- Check if the player is in combat:
         if not UnitAffectingCombat("player") then
             -- ...if not, call the original function:
             original_UnitFrame_OnEnter(frame)
         end
         -- Otherwise, do nothing.
     end
    

    Yeah that's going to taint your UI. It's a bad idea.

    I see, maybe I can add the HookScript():

     -- Get a pointer to the original function:
     local original_UnitFrame_OnEnter = UnitFrame_OnEnter 
     -- Hook the original function with a new one: 
     UnitFrame:HookScript("OnEnter", function(frame)
         -- Check if the player is in combat:
         if not UnitAffectingCombat("player") then
             -- ...if not, call the original function:
             original_UnitFrame_OnEnter(frame)
         end
         -- Otherwise, do nothing.
     end)
    

    When posting code, just highlight the code and click the code button. Then it will be displayed properly.